Differences between static class and instance class with private constructor - c#

Although a static class has only one instance and can't be instantiated, a class with a private constructor can't be instantiated (as the constructor can't be seen), so every time you call this class, this is the same one instance?
Factory classes always follow the last convention (instance class with private constructor). Why is this?
Thanks

There's nothing stopping the class with the private constructor from having a public static method which returns instances of the class:
public class NoPublicConstructor
{
private NoPublicConstructor()
{
}
public static NoPublicConstructor NewInstance()
{
return new NoPublicConstructor();
}
}
As you can see, the static method does not return the same one instance.
edit: One of the reasons factory classes do this is to be able to separate responsibility in future versions: while your code always calls the factory creation method, the author may move all the "guts" out of that class into a different one and your code won't need to know the difference. Calling that class' (public) constructor ties it to an extent to the original class implementation.

You can't* get an instance from outside the class, but you can from inside. A static method or an inner class can create and return an instance of the class with a private constructor. The static class cannot be instanced by anything.
class Foo
{
private Foo()
{
}
public class Bar
{
public Bar()
{
}
public Foo GetFoo()
{
return new Foo();
}
}
}
..
Foo.Bar fooBar = new Foo.Bar();
Foo foo = fooBar.GetFoo();
Edit: *I use the term "can't" loosely. Brian Rasmussen pointed out in the comments to the OP that another method to obtain an instance is through a call through System.Runtime.Serialization.FormatterServices, and this is external to the class itself.
Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));

Creating a class with private constructor is the common pattern for implementing a "Singleton" object.
The Singleton usually will instantiate an instance of itself, and only allow access to it through a static "Instance" property, which means there's only ever one instance of the class.
The advantage of using a Singleton over a purely static class is that you can utilize interfaces and different implementation classes within the singleton. Your "Singleton" might expose an interface for a set of methods, and you can choose which exact implementation class to instantiate under the covers. If you were using a purely static class, it would be hard to swap out a completely different implementation, without impacting other code.
The main downside of Singleton is that it's difficult to swap out the implementation class for testing, because it's controlled within the Singleton private methods, but there are ways to get around that.

Related

Child static constructor not called when base member accessed

I have a class defined as:
public class DatabaseEntity<T> where T : DatabaseEntity<T> {
public static string Query { get; protected set; }
public static IList<T> Load() {
return Database.Get(Query);
}
}
public class Node : DatabaseEntity<Node> {
static Node() {
Node.Query = #"SELECT Id FROM Node";
}
}
When I run Node.Load() from a codebehind (Window.xaml.cs) the Node's static constructor never fires; or at least doesn't hit a breakpoint and does not set Node.Query to anything other than null.
Is there any reason why this might occur?
Solution
Check out the answers below for a few solutions. For my case, I decided to simply make the Query variable public, and set all instances of Query in one place. (Not ideal, but it works.)
The problem lies in your assumptions about when a static constructor is called. The documentation, which isn't the clearest, states that
It is called automatically before the first instance is created or any static members are referenced.
You may assume that if you call
Node.Load();
that you are calling a static method on the Node class, but in fact you're calling it on the base class, as that is where it is implemented.
So, to fix this, you have two choices. First, you can trigger the static constructor explicitly by creating a new instance of the Node class prior to calling Load()
var foo = new Node(); // static ctor triggered
Node.Load();
or create a protected virtual member that the base class can call in order to get the query value (can't use abstract here, unfortunately)
public class DatabaseEntity<T> where T : Derp {
protected abstract string Query { get; }
public static IList<T> Load() {
return Database.Get(new DatabaseEntity<T>().Query);
}
}
Both of which are hacky. Better to dispense with the statics altogether and go with instance methods. Statics should be used sparingly, as they result in tight coupling and other design headaches such as this.
Yes, static constructors will not be called till the members of the class is first accessed or first instance is created.
In your case you're accessing DatabaseEntity<T>.Load, so static constructor of DatabaseEntity<T> will be called not its derived class ones.
Even though you call Node.Load it is mapped to DatabaseEntity<Node> at compile time. So technically you're not accessing Node class at all.
You can also call class constructors directly using System.Runtime.CompilerServices and the RuntimeHelpers type by doing something as follows:
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
So for example you could use reflection to loop over all types in an inheritance chain and call each of the static constructors.

static keyword when creating instance

I came across the following code.
public class Test
{
public static Test Create()
{
return new Test
{
a1 =1,
b1="abc"
};
}
:
:
:
}
And in the calling class it is instantiated as below
static Test model = Test.Create();
What is the use of static keyword in the above line? What will be the difference if we don't use the static keyword? I'm using .NET 4 and VS 2010
EDIT
I know what is static in c#. The main reason I asked this question is why is it used when creating instance of class?
In this concrete presented code, don't see much sence of using this technique, but usually
you can do this in order to control your type instances creation.
For example: immagine that your class interacts with some COM object of the client, that can not be instantiated more the 10 times. To control that consumer of your API will not create more then 10 instances of your type, you can use this technique.
public class MyComWrapper {
private MyComWrapper () {} // MAKE CTOR PRIVATE SO NOONE CAN CREATE
// AN INSTANCE OF YOUR CLASS IF NOT WITH
// `static` METHOD CALL
static int counter = 0; //INSTANCE COUNTER
public static MyComWrapper Create()
{
if(counter >10) //MORE THEN 10, BAD !
throw new InvalidOperationException("Can not instantiate more then 10 instances");
counter ++;
return new Test
{
a1 =1,
b1="abc"
};
}
}
The static keyword makes it available without instantiating the object. The author is creating a function to instantiate the object in a specific way, but since it's the default constructor anyone can instantiate it.
Although not exclusively, along with making the constructor private, this is a pattern commonly used in the Singleton Pattern.
Static modifier belongs to the type itself rather than to a specific object.
You don't have to create an instance to use that static function. you can directly use the static function without creating an instance of the class.
If the static keyword is applied to a class, all the members of the class must be static.
It is simple. They are separate uses of static. The first one creates a static method in a non-static class. The second one create a static member of the "calling" class.
Your Test class itself is not static, so you are allowed to instantiate it.
To answer your question: if you do not use the static keyword in the calling class, it will be a "normal" instance member.

How are static constructors and private constructors different?

How are static constructors and private constructors different?
public class WorkstationDevicePresenter
{
private WorkstationDevicePresenter()
{}
}
What's the point in leaving them blank?
Whats the point in leaving them blank?
There are a number of reasons to make "blank" constructors.
You might make a blank constructor because you want a place to set a breakpoint during debugging.
You might make a blank static constructor because doing so changes the semantics of static field initializers. Read Jon's article on the subject for details.
Let's leave static constructors and consider blank instance constructors.
The key rule that motivates blank constructors is: By default if there are no constructors in a type then you get a "blank" parameterless public constructor for free. If there are any constructors in a type then you do not get a blank parameterless public constructor for free.
So the first obvious reason why you'd want a blank constructor is: I want a blank parameterless constructor, but I've already made another ctor, so I no longer get one for free.
The second reason is that you don't have any ctors and you do not want a blank parameterless public constructor. You might want a blank parameterless private, internal or protected constructor. If that's what you want then you'll have to make one yourself.
In particular, making an empty private ctor as the only ctor means that the class cannot be instantiated via a constructor from outside the class. This is very useful if you want to use the factory pattern. It also prevents code outside the class from making derived classes, because derived classes must be able to call a constructor. If all the constructors are private then they can't derive.
I frequently use this variation on the factory pattern:
public abstract class Thing
{
private Thing() {}
private class RedThing : Thing { ... }
public static Thing GetRedThing() { return new RedThing(); }
}
See, by making a private constructor I can make a public abstract class that can only be instantiated by my code and only extended by my code, and therefore I have a nice invariant: every time I see an object of type Thing, I know where it came from.
Static constructors happen once when the class is loaded, private constructors happen when they are called by some public static method typically used to create singletons, or with the Builder pattern. There is no reason to have a blank private constructor (that I know of).
Static constructors initialize the static parts of a class and private constructors can only be used by the class itself, like for creating a singleton-object of the class.
public class MyClass {
private static int staticitem;
private int instanceitem;
static MyClass(){
staticitem = 0; //define value for staticitem
}
private MyClass() { //can only be called from within the class
instanceitem = 0; //define value for instanceitem
}
public static MyClass GetMyClass() {
MyClass m = new MyClass();
return m;
}
}
Blank private constructor will make the class uninstantiable by anything other than itself. If you don't have this piece of code, by default the compiler creates a blank public parameterless contstructor.
Static constructor is called when creating the static instance.
You can use both to create a Singleton pattern, for instance.
Check the following code:
public class Singleton
{
public static Singleton Instance;
static Singleton
{
Instance = new Singleton();
}
private Singleton()
{
}
}
public class SomeOtherClass
{
public static Singleton CompileError = new Singleton();
public static Singleton CompileOK = Singleton.Instance;
}

Prevent a subclass of a singleton class from calling the singleton's constructor

Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data. By subclassing, I can access members of either the global class or subclass. And by using a singleton class, I can change the global variables anywhere and have them be reflected in all the subclasses.
However, I'm getting stuck because the base class's constructor wants to call the singleton class's constructor, but it can't as it's marked private.
how do I get around this? Is what I'm trying to do possible? I went down this path due to responses to this post: Can I make a "global" object to store variables for multiple objects?
For example,
public class GraphMasterObject {
private static GraphMasterObject instance;
private GraphMasterObject() { }
}
public static GraphMasterObject Instance {
get {
if (instance == null) instance = new GraphMasterObject();
return instance;
}
}
public int globalVar=10;
}
public class GraphObject : GraphMasterObject {
public GraphObject() {
}
public int localVar=20;
}
I want to be able to do
GraphObject go = new GraphObject();
go.globalVar <- this is 10
GraphMasterObject.Instance.globalVar = 20;
go.globalVar <- now this is 20
Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data.
That's a problem to start with. As soon as you have a class which has subclasses, that it by definition not a singleton. Someone can add another subclass at any point, and even if you only have one instance of each subclass, you'll have two distinct instances which are compatible with the base class.
You could add something in the base class constructor to throw an exception if there's already an instance, but it would be pretty smelly. Fundamentally, singletons are incompatible with subclassing. Rethink your design. (Ideally, avoid the singleton pattern in the first place, but that's another matter...)

Nested class with hidden constructor impossible in c#?

I' ve been doing some programming lately and faced an issue which i found weird in c#. (at least for me)
public class Foo
{
//whatever
public class FooSpecificCollection : IList<Bar>
{
//implementation details
}
public FooSpecificCollection GetFoosStuff()
{
//return the collection
}
}
I want the consumer of Foo to be able to obtain a reference to FooSpecificCollection, even perform some operations on it. Maybe even set it to some other property of Foo or smth like that, but not To be able to CREATE an instance of this class. (the only class that should be able to instatiate this collection should be Foo.
Is my request really that far-fetched? I know that people way smarter defined c# but shouldn't there be such an option that a parent class can create a nested class instance but nobody else can't.
So far I created a solution to make an abstract class, or interface available through the property and implement a concrete private class that is not available anywhere else.
Is this a correct way to handle such a situation.?
The way embedded classes work is that they, as members of the outer class, get access to private members of that outer class. But not the other way around (what is what you want).
You can shield the constructor of FooSpecificCollection, but then the Factory has to be part of FooSpecificCollection itself. It could enlist the outer class:
public class Foo
{
public class FooSpecificCollection : List<Bar>
{
private FooSpecificCollection () { }
public static FooSpecificCollection GetFoosStuff()
{
var collection = new FooSpecificCollection ();
PrepareFooSpecificCollection(collection);
return collection;
}
}
private static void PrepareFooSpecificCollection(FooSpecificCollection collection)
{
//prepare the collection
}
}
Make your nested class private and make the return value of GetFoosStuff IList<Bar> instead of FooSpecificCollection.
Also, there's a good chance that deriving from List<Bar> is a bug.
If you are creating a library for others to use, you could make the constructor internal. Anyone outside the library will not be able to access it. If you are concerned about calling the constructor in your own project, just don't call it outside the parent class.
We create classes all the time which are not directly related to other classes, but the constructors don't have to be hidden from non-related classes. We (the programmers) know the the objects are not related so we don't ever create an instance of one in the other.
There is a solution but I don't think I would use it in my App :)
The idea is to have derived class from FooSpecific which is private and can be used only inside Foo but has public constructor, so Foo can create its instances.
public class Foo
{
//whatever
public class FooSpecific
{
// Protected contructor.
protected FooSpecific()
{
}
// All other code in here.
}
// Private helper class used for initialization.
private class FooSpecificInitHelper : FooSpecific
{
public FooSpecificInitHelper()
{
}
}
// Method in foo to create instaces of FooSpecific.
private FooSpecific CreateFooSpecific()
{
return new FooSpecificInitHelper();
}
}
No, and it doesn't really make sense.
I mean the whole point is so that you could potentially return other instances; but who will be deriving from that class anyway? Certainly not any other classes (Because that would be wrong, and imply it shouldn't be hidden inside the main class), so ...

Categories

Resources