Child static constructor not called when base member accessed - c#

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.

Related

How to initialize static fields in subclasses

I have an abstract base class, and subclasses who all have an automatically generated Instance static field of their own type, done through using genericity "in between" the base and sub classes (see code below).
When those instances are created, I register them in a dictionary based on specific "identifying" fields overwritten in subclass constructors, in order to access them somewhere else in the code.
I could register them in their constructors, however I don't want to have to drag and copy/paste this same bit of code in every such subclass in order to register them.
public abstract class BaseClass
{
// Declaration of fields and methods
}
public class GenericBaseClass<T> : BaseClass where T : GenericBaseClass<T>
{
private static T instance = ((T) Activator.CreateInstance(typeof(T), true)).Register();
public static T Instance => instance;
public T Register()
{
// Registers Instance in a dictionary.
}
}
public class Subclass1 : GenericBaseClass<Subclass1>
{
private Subclass1()
{
// Modification of protected fields.
}
}
Doing this enables me to call Subclass1.Instance, and by doing so, this instance gets registered in my dictionary, however it doesn't get registered before I try to access it, and only Subclass1 gets that treatment, not other subclasses.
I followed this answer https://stackoverflow.com/a/34726769/13738641 (in the updated section) and made a static constructor for BaseClass and for GenericBaseClass hoping it would initialize static fields for those subclasses, to no avail.
It appears from debugging that the BaseClass static constructor is indeed called, and it does fetch the right subclasses, but it doesn't throw an error, nor does it calls the subclass (static) constructors. Now I could be going crazy, but I could have sworn it worked once before I tried modifying something before reverting back to that, only for it not to work anymore.
I've tried adding a static constructor to the generic class which I hoped would be called once for each subclass, but this constructor only gets called once (when I access some subclass's instance in order to trigger the BaseClass static constructor call).
Any suggestion on what to do to achieve this? I accept suggestion on other ways to achieve something similar (i.e. keep a dictionary generated at runtime with instances of my classes), the subclasses being singletons isn't critical, so maybe I could register constructors instead of instances in the dictionary? I have no idea if that is even possible, with each constructor returning a different type.
You could loop through the types in your assembly and check if they implement the generic class, and then invoke the static constructor of the generic class (which will implicitly invoke the static constructor of the sub class because of Activator.CreateInstance) by calling RuntimeHelpers.RunClassConstructor. So just add a method that does that can call it:
public static void RegisterAll()
{
foreach(var type in typeof(BaseClass).Assembly.GetTypes().Where(t => t.BaseType.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(GenericBaseClass<>)))
{
RuntimeHelpers.RunClassConstructor(type.BaseType.TypeHandle);
}
}

How to ensure Static Properties get initialized after Global.Application_Start code?

How do I ensure that the Factory class' properties get initialized after Application_Start?
public static class Globals
{
public Static Customer Cust {get;set;}
}
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
Globals.Cust = GetCustomerFromDataBase();
}
}
public static class Factory
{
public static Customer Cust => Globals.Cust ;
}
The Factory.Customer gets called by a method inside a webapi controller.
The answer to your question depends on your code. If as you say, Factory.Cust is first referenced in a WebAPI Controller method, then you should be safe; the Application_Start method should have run before anything in one of your controllers.
Your Factory.Cust property doesn't get initialized. When someone tries to read the value of Factory.Cust, all that happens is that the Globals.Cust property (getter) is executed (remember, properties are really code, not just state). As long as Globals.Cust is initialized before Factory.Cust is read, you are safe. If you test your code (by putting breakpoints here and there) and it seems to follow what I'm saying, you should be OK.
What I was saying in the comments about static classes is that a static class can have a constructor. It can be explicit (you write a constructor for the class), but it can also have other code you have in your class. For example, if, in your Factory class, you had code that looked like:
private static Customer _localCustomerStuff = new Customer();
Then the code that's associated with that field would be folded into the Factory constructor. Property initializers like the one below also do the same kind of thing (since they are initializing the hidden backing store for the property).
public static string SomeString { get; set; } = "SomeString Initial Value";
You don't know exactly when a static class's constructor code will run, but there is a guarantee made by the framework that it will run before any reference to that class is made. If you access the Factory class, and you had some initialization associated with that class (none of which you show in your post above), then you can be sure that the initialization will have started before you access anything to do with the class.
Take a look at Static Constructor Docs to see what I'm talking about.

Private class with Public method?

Here is a piece of code:
private class myClass
{
public static void Main()
{
}
}
'or'
private class myClass
{
public void method()
{
}
}
I know, first one will not work. And second one will.
But why first is not working? Is there any specific reason for it?
Actually looking for a solution in this perspective, thats why made it bold. Sorry
It would be meaningful in this scenario; you have a public class SomeClass, inside which you want to encapsulate some functionality that is only relevant to SomeClass. You could do this by declaring a private class (SomePrivateClass in my example) within SomeClass, as shown below.
public class SomeClass
{
private class SomePrivateClass
{
public void DoSomething()
{
}
}
// Only SomeClass has access to SomePrivateClass,
// and can access its public methods, properties etc
}
This holds true regardless of whether SomePrivateClass is static, or contains public static methods.
I would call this a nested class, and it is explored in another StackOverflow thread.
Richard Ev gave a use case of access inside a nested classes. Another use case for nested classes is private implementation of a public interface:
public class MySpecialCollection<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return new MySpecialEnumerator(...);
}
private class MySpecialEnumerator : IEnumerator<T>
{
public bool MoveNext() { ... }
public T Current
{
get { return ...; }
}
// etc...
}
}
This allows one to provide a private (or protected or internal) implementation of a public interface or base class. The consumer need not know nor care about the concrete implementation. This can also be done without nested classes by having the MySpecialEnumerator class be internal, as you cannot have non-nested private classes.
The BCL uses non-public implementations extensively. For example, objects returned by LINQ operators are non-public classes that implement IEnumerable<T>.
This code is syntactically correct. But the big question is: is it useful, or at least usable in the context where you want to use it? Probably not, since the Main method must be in a public class.
Main() method is where application execution begin, so the reason you cannot compile your first class (with public static void Main()) is because you already have Main method somewhere else in your application. The compiler don't know where to begin execute your application.
Your application must have only one Main method to compile with default behavior otherwise you need to add /main option when you compile it.

Differences between static class and instance class with private constructor

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.

Private constructor and public parameter constructor

I heard that a private constructor prevents object creation from the outside world.
When I have a code
public class Product
{
public string Name { get;set;}
public double Price {get;set;}
Product()
{
}
public Product(string _name,double _price)
{
}
}
Here I still can declare a public constructor (parameter), won't it spoil the purpose of the private constructor? When do we need both private and public constructor (parameter) in code?
I need a detailed explanation please.
The reason you would use the pattern you're describing is when you want to control how the object is instantiated.
In your example, for instance, you're saying the only way to create a Product is by specifying its name and price. This is with respect to the outside world, of course. You could also do something similar using other access modifiers, and it would have different implications, but it all boils down to controlling how you want the objects instantiated with respect to who will be doing it.
If you wanted to prevent object creation altogether you would have to make all your constructors private (or protected). That would force the object to be created from within itself (or an inherited class).
Also, as Matti pointed out in the comment below, when you define a constructor that is parameterized you don't need to specify a private default constructor. At that point it is implied.
Constructors can be chained together to avoid having to duplicate code. It is quite common to have private constructors, that nobody is supposed to call outside of the class, that are chained from a public constructor.
Example:
public class Test
{
private Test(int? a,string b) { }
public Test(int a) : this(a, null) { }
public Test(string b) : this(null, b) { }
}
Here there are two public constructors, one taking a string and one taking an int. They both chain to the common private constructor that takes both arguments.
Also, you can construct new objects from within the same class by using the private constructor. For instance, when you want specialized constructors only available through static factory methods:
public static Test Create()
{
int? a = ReadConfigurationForA();
string b = ReadConfigurationForB();
return new Test(a, b);
}
When it is not be a good idea to expose a private constructor to the outside world, add a static factory method that fetches the correct arguments to pass on the constructor.
You need a private constructor when you only want that constructor to be called from within the class itself. In your example you are forcing the calling object to provide 2 parameters when creating the object.
With a private constructor you could do something like:
public static GetInstance ()
{
return new YourObject();
}
but nothing else except the object could call the parameterless constructor.
It's commonly used to create a singleton pattern:
http://www.dofactory.com/Patterns/PatternSingleton.aspx
You would use a constructor with parameters when you wanted to force calling code to pass a value to the constructor in order to create an instance of your class. In your example, calling code must use the parameter version of the constructor in order to create a Product.
A private constructor is a special instance constructor. It is commonly used in classes that contain static members only. If a class has one or more private constructors and no public constructors, then other classes (except nested classes) are not allowed to create instances of this class.
For more details refer to this:
http://msdn.microsoft.com/en-us/library/kcfb85a6(VS.80).aspx

Categories

Resources