I am reading Josh Bloch's book Effective Java and he suggests using a builder design pattern when building objects that have large amounts of members. From what I can see it isn't the vanilla design pattern but looks like his variation. I rather like the look of it and was trying to use it in a C# web application that I am writting. This is the code written in Java and works perfectly
public class Property {
private String title;
private String area;
private int sleeps = 0;
public static void main(String[] args) {
Property newProperty = new Property.Builder("Test Property").Area("Test Area").Sleeps(7).build();
}
private Property(Builder builder) {
this.title = builder.title;
this.area = builder.area;
this.sleeps =builder.sleeps;
}
public static class Builder{
private String title;
private String area;
private int sleeps = 0;
public Builder (String title){
this.title = title;
}
public Builder Area(String area){
this.area = area;
return this;
}
public Builder Sleeps(int sleeps){
this.sleeps = sleeps;
return this;
}
public Property build() {
return new Property(this);
}
}
}
When I put this into what I think is the C# equivalent
public class Property
{
private String title;
private String area;
private Property(Builder Builder)
{
title = Builder.title;
area = Builder.area;
}
public static class Builder
{
// Required parameters
private String title;
private String area;
// Optional parameters
private int sleeps = 0;
public Builder(String val)
{
this.title = val;
}
public Builder Area(String val)
{
this.area = val;
return this;
}
public Builder Sleeps(int val)
{
this.sleeps = val;
return this;
}
public Property build()
{
return new Property(this);
}
}
}
Then I get compiler warnings. Most of them "cannot declare instance members in a static class".
So my question is firstly what have I missed? If I have missed something, can I do it in the manner Josh Bloch recommends but in C#, and lastly, and this one important too, is this thread-safe?
public static class in Java means that you define a static nested class. That means that it is logically contained in another class but instances of it can exist without a reference to it's outer class. A non-static nested class is called an "inner class" and instances of it can only ever exist in relation to an instance of the outer class.
In C# a static class is one that can't be instantiated and thus can't have any non-static members. There is no direct language-level equivalent to this construct in Java, but you can easily prevent instantiation of a Java class by providing only a private constructor.
Short Java recap:
All Classes defined inside another Class are "nested Classes"
nested Classes that are not static are called inner Classes
instances of inner Classes can only exist in relation to an instance of the outer Class
static nested Classes have no separate name
static nested Classes are largely independent from their outer class (except for some privileged access).
I'd be happy if some C# guru told us how inner/nested classes are handled in C#/.NET.
I think you can achieve pretty much the same effect if you create Builder as a top level class ( for that's exactly what it is in Java ) and create a factory method to receive the builder in order to keep the constructor private ( which in turn would let you return subclasses instances if needed).
The point is to let the builder perform the steps needed to create the object.
So ( without knowing much about C# you could try something like this )
// My naive C# attempt:P
public class Property
{
public static void main( String []args )
{
Property p = Property.buildFrom( new Builder("title").Area("area").Etc() )
}
public static Property buildFrom( Builder builder )
{
return new Propert( builder );
}
private Property ( Builder builder )
{
this.area = builder.area;
this.title = builder.title;
// etc.
}
}
public class Builder
{
public Builder ( String t )
{
this.title = t;
}
public Builder Area( String area )
{
this.area = area;
return this;
}
// etc.
}
The whole point of having Builder as an static inner class of property is to create a high coupling among the two ( as if they where one ). That's why build method in Builder calls the private "Property" constructor.
Probably in C# you could use an alternate artifact to create the same coupling.
saua has the right answer, but I would like to be clear about your example in particular:
In the C# version, you should remove the static keyword from the inner class. It doesn't mean the same thing as the Java version, and indeed the effect it has in the Java version is the normal behaviour for inner classes in C#.
In Java a nested class is by default associated with a particular instance of its containing class. An instance of the nested class can access variables and methods of the containing instance. If the nested class has the "static" keyword then it is not associated with an instance of the outer class. It is in this sense that Bloch uses the "static" keyword on the Builder class.
"Static" means something different when applied to a nested class in C#. I don't know what keyword you would use in C#, or even if it is necessary. Did you try leaving the static keyword out of the class definitions?
Use of "static" in Java class definitions is discussed in Item 18 of Effective Java.
I'm not sure what Java is doing with the static class declaration, but in C#, a static class is one that only has class-level members and, by definition, can not be implemented into an instance. It's like the old VB difference between Class and Module.
I don't know why C# is complaining, but I can say that the code is thread-safe. If you were creating two or more instances of Property at the same time, each in their own threads, you wouldn't run into any problems.
I will try removing the static keyword. My other thought was, as others have already suggested, was to create the builder class as a top level class.
To answer several comments about how to get Java's inner class behavior in C#, it would seem that the reference to the enclosing class needs to be passed in the constructor of the inner class (from a quick Google - C# may have since added the capability).
public class Outer
{
...
void SomeMethod() {
Inner workerBee=new Inner(this);
}
...
class Inner
private Outer outer;
{
Inner(Outer out) {
outer=out;
}
}
}
So C# just makes explicit what Java did implicitly, including explicitly needing the reference to access members of the outer class.
Personally, I have never liked the Java implicit accesses to the outer classes members, since it seems too easy to trip up and accidently break encapsulation - I nearly always create my inner classes as static and pass them a reference to the outer class.
Assuming that your class has publicly settable properties corresponding to the builder members, you don't need Bloch's builder pattern in C#. You can use Object Initializers:
public class Property
{
public String Title {get; set};
public String Area {get; set};
public int Sleeps {get; set};
public static void main(String[] args)
{
Property newProperty = new Property {Title="Test Property", Area="Test Area", Sleeps=7};
}
}
This won't be possible if you need more encapsulation.
Related
How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
In C++ I can declare a fully functional anonymous class inside a piece of code where it's needed so that I don't have to declare it if I need it only once.
The code should be like this
Class MyClass
{
Class
{
String string1;
String string2;
void MyMethod();
} Strings;
}
And call it the members with MyClass.Strings.string1, MyClass.Strings.MyMethod() and so on. This way I can elegantly group my code.
Is there a way to do the same thing in C#?
This way I can elegantly group my code.
I don't how can this help you to elegantly group your code, but there is no such thing in C#. There are anonymous classes but they only work in local scopes:
// inside a method:
var obj = new { String1 = "Hello", String2 = "World" };
And you can't add methods to them.
The closest thing you can get to is an inner class/struct:
class MyClass
{
class MyStrings
{
String string1;
String string2;
void MyMethod() { ... }
}
MyStrings Strings;
}
I agree Sweeper. This functionality adds just cluttering code. You should consider to make your code as easy as possible to understand. This means if you feal that you want to group your code, giving every group it´s own functionality, why not make this group a class and give it a name that directly reflects what its purpose is.
What you can do is use an anonymous class which in C# doesn´t implement any interface but just derives from object:
var a = new { MyMember = 1, MyFunc = new Func<int>(() => 1) };
now you can invoke both members of this type:
Console.WriteLine(a.MyMember);
var retVal = a.myFunc();
But does this make your code any better in a way that it´s easier to understand what it does? I doubt so. Give your instances - even when used only once - a name that describes what their intention - the idea behind - is. Don´t make it hard for others to understand your code by cryptifying it.
Apart from this you can restrict the use of your class to be private by nesting it within another one:
public class MyClass
{
private class Strings { /* ... */ }
}
Now your class is just visible to itself and within MyClass (and in other classes that are nested in MyClass of course). This makes it impossible to access the class from the outside like so:
var strings = new MyClass.Strings();
Try making the inner class static. That way you will be able to use the syntax you describe:
class MyClass {
public static Strings {
public static string string1;
public static string string2;
public static void MyMethod() {}
}
}
You can then call: MyClass.Strings.string1 = "Hell, world!";
What is the need of private constructor in C#?
I got it as a question for a C# test.
For example if you have a class that should only be created through factory methods. Or if you have overloads of the constructor, and some of them should only be used by the other constructors. Probably other reasons as well =)
If you know some design pattern, it's obvious: a class could create a new instance of itself internally, and not let others do it.
An example in Java (I don't know C# well enough, sorry) with a singleton-class:
class Meh
{
private Meh() { }
private static Meh theMeh = new Meh();
public static Meh getInstance() { return theMeh; }
}
Whenever you want to prevent direct instantiation of a class from outside of it, you'll use a private constructor. For example, prior to C# 2.0 which introduced static classes, you used a private constructor to accomplish roughly the same thing:
sealed class StaticClass {
private StaticClass() {
}
public static void DoSomething() {
}
}
When you want to prevent the users of your class from instantiating the class directly. Some common cases are:
Classes containing only static methods
Singletons
I can can recall few usages for it:
You could use it from a static factory method inside the same class
You could do some common work inside it and then call it from other contructure
You could use it to prevent the runtime from adding an empty contructure automatically
It could be used (although private) from some mocking and ORM tools (like nhibernate)
For example when you provide factory methods to control instantiation...
public class Test(){
private Test(){
}
void DoSomething(){
// instance method
}
public static Test CreateCoolTest(){
return new Test();
}
}
Private constructors are used to prevent the creation of instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the entire class static. For more information see Static Classes and Static Class Members.
class NLog
{
// Private Constructor:
private NLog() { }
public static double e = System.Math.E; //2.71828...
}
The following is an example of a class using a private constructor.
public class Counter
{
private Counter() { }
public static int currentCount;
public static int IncrementCount()
{
return ++currentCount;
}
}
class TestCounter
{
static void Main()
{
// If you uncomment the following statement, it will generate
// an error because the constructor is inaccessible:
// Counter aCounter = new Counter(); // Error
Counter.currentCount = 100;
Counter.IncrementCount();
System.Console.WriteLine("New count: {0}", Counter.currentCount);
}
}
While this link is related to java, I think it should help you understand the reason why as the idea is pretty much the same.
Private constructors prevent a class from being explicitly instantiated by callers. There are some common cases where a private constructor can be useful:
classes containing only static utility methods
classes containing only constants
type safe enumerations
singletons
You can use it with inheritance in a case where the arguments to the constructor for the base class are of different types to those of the child classes constructor but you still need the functionality of the base class in the child class eg. protected methods.
Generally though this should be avoided wherever possible as this is a bad form of inheritance to be using.
I'm late to the game, but reading through all the other answers, I don't see this usage mentioned:
I use private constructors in scenarios where I have multiple (public) constructors, and they all have some code in common. With constructor chaining, the code becomes really neat and DRY.
Remember, the private readonly variables can only be set in constructors, so I can't use a regular method.
Example:
public class MyClass
{
private readonly int _a;
private readonly int _b;
private readonly string _x;
public MyClass(int a, int b, string x)
: this(x)
{
_a = a;
_b = b;
}
public MyClass()
: this("(not set)")
{
// Nothing set here...
}
private MyClass(string x)
{
_x = x;
}
}
Basically you use private constructors when you are following a singleton design pattern. In this case, you have a static method defined inside the class that internally calls the private constructor.
So to create the instance of the class for the first time, the user calls the classname.static_method_name. In this method, since the class's object doesn't yet exist, the static method internally calls the private constructor and returns the class's instance.
If the class's instance already exists, then the static method simply returns the instance to the calling method.
And of course you can use private constructor to prevent subclassing.
I am converting Java into C# and have the following code (see discussion in Java Context about its use). One approach might be to create a separate file/class but is there a C# idom which preserves the intention in the Java code?
public class Foo {
// Foo fields and functions
// ...
private static class SGroup {
private static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();
public SGroup(int id, String type) {
// ...
}
}
}
All C# nested classes are like Java static nested classes:
C#:
class Outer
{
class Inner
{
}
}
Is like Java's:
class Outer
{
static class Inner
{
}
}
In other words, an instance of Inner doesn't have an implicit reference to an instance of Outer.
There isn't the equivalent of a Java inner class in C# though.
The accessibility rules are somewhat different between the two languages though: in C#, the code in the nested class has access to private members in the containing class; in Java all code declared within one top-level type has access to all the other private members declared within that same top-level type.
Give this a look
http://blogs.msdn.com/oldnewthing/archive/2006/08/01/685248.aspx
I am looking specifically at
In other words, Java inner classes are
syntactic sugar that is not available
to C#. In C#, you have to do it
manually.
If you want, you can create your own
sugar:
class OuterClass {
...
InnerClass NewInnerClass() {
return new InnerClass(this);
}
void SomeFunction() {
InnerClass i = this.NewInnerClass();
i.GetOuterString();
}
}
Where you would want to write in Java
new o.InnerClass(...) you can write in
C# either o.NewInnerClass(...) or new
InnerClass(o, ...). Yes, it's just a
bunch of moving the word new around.
Like I said, it's just sugar.
You can have a static nested class in C#, according to Nested Classes.
All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)