In Java I can write:
public class Foo {
public static Foo DEFAULT_FOO;
static {
DEFAULT_FOO = new Foo();
// initialize
DEFAULT_FOO.init();
}
public Foo() {
}
void init() {
// initialize
}
}
How can I get the same functionailty in C# (where static members are initialized before use)? And, if this is a bad thing to try to do, what is a better approach?
you use a static constructor, like this:
public class Foo
{
static Foo()
{
// inits
}
}
Here's more info.
Bottom line: it's a paramaterless constructor with the static keyword attached to it. Works just like the static block in Java.
Edit: One more thing to mention. If you just want to construct something statically, you can statically initialize a variable without the need for the static constructor. For example:
public class Foo
{
public static Bar StaticBar = new Bar();
}
Keep in mind that you'll need a static constructor if you want to call any methods on Bar during static initialization, so your example that calls Foo.Init() still needs a static constructor. I'm just sayin' you're not limited, is all. :)
Static is still the keyword in C#:
public class Foo {
public static Foo DefaultFoo;
static Foo {
DefaultFoo = new Foo();
// initialize
DefaultFoo.init();
}
public Foo() {
}
void init() {
// initialize
}
}
Related
While searching for ways to get an instance of a singleton class i found many different approaches (some simple, some convoluted) but when messing around i found a way to do it which i didn't find anywhere else.
So what i basically do is:
public class Foo
{
public static Foo Invoker;
public Foo()
{
Invoker = this;
}
public void Method1()
{
//.....
}
}
And then from another class
public class Foo2
{
public Foo2()
{
//.....
}
public void Main()
{
var foo = Foo.Invoker;
//or
Foo.Invoker.Method1();
}
}
My app is single threaded so i don't care about thread safety (should i?) , so are there any other problems that this approach could cause that i am missing?
First of all, your 'singleton' pattern is quite easy to break. Let's say I'd create two instances of Foo in your application (changing the name of the class Foo1 to Bar for clarity):
var firstFoo = new Foo();
var bar = new Bar();
// Will access firstFoo when it calls Foo.Invoker
bar.Main();
var secondFoo = new Foo();
// Will access secondFoo when it calls Foo.Invoker. Huh?
bar.Main();
Another problem: Let's say I use Bar, without having initialized any Foo instances:
var bar = new Bar();
// Will throw a NullReferenceException, because Foo.Invoker is not yet initialized.
bar.Main();
As a rough rule of thumb, you should not set static fields from instances, because it leads to these kinds of situations.
Secondly, Bar probably does not need to know that Foo is a singleton in the first place. You could simply inject Foo in Bar's constructor.
public class Bar
{
private Foo foo;
public Bar(Foo foo) => this.foo = foo ?? throw new ArgumentNullException(nameof(foo));
public void Main()
{
// Now we know it is not null and, for Bar, it does not matter whether it's a singleton or not.
foo.Method1();
}
}
This way you could manage Foo instances easier in your application:
var firstFoo = new Foo();
var bar = new Bar(firstFoo);
// Does not make a difference now.
var secondFoo = new Foo();
This way, you could also leverage dependency injection containers like NInject or Microsoft.Extensions.DependencyInjection to manage your singletons for you.
If you really do want to create a single threaded singleton pattern, I would read Jon Skeet's blog post about singletons (good read!).
The simplest way of creating a singleton would be this approach. This way you create a single instance of Foo on the static property, that can never be changed. But read the blog post for more advanced patterns:
public class Foo
{
public static Foo Invoker { get; } = new Foo();
// Private constructor makes sure the only instance of Foo is created here.
private Foo()
{
}
}
Edit
If you'd want to make sure that all references to Foo in your application point to the last created instance of Foo, you could try something like this:
interface IFoo
{
void Method1();
}
class Foo : IFoo
{
private static int index = 1;
private int id;
private static NestedFoo invoker = new NestedFoo();
public static IFoo Invoker
{
get
{
if (invoker.Instance == null)
{
Create();
}
return invoker;
}
}
private Foo(int id) => this.id = id;
public static IFoo Create()
{
var foo = new Foo(index++);
invoker.Instance = foo;
return invoker;
}
public void Method1()
{
Console.WriteLine(this.id);
}
private class NestedFoo : IFoo
{
public Foo Instance { get; set; }
public void Method1() => Instance.Method1();
}
}
Now you'll always have a reference to the same instance of foo:
var foo = Foo.Create();
foo.Method1(); // 1
var foo2 = Foo.Create();
foo.Method1(); // 2
foo2.Method1(); // 2
Suppose I have these 2 classes:
public class A<T> where T : IEntityWithID, new()
{
private static EntityInfo entityInfo = B.GetEntityInfo(typeof(T));
private static IEnumerable TestCases
{
// Do work with entityInfo...
}
}
private static class B
{
private static IList<EntityInfo> entityInfoList = B.GetEntityList();
public static EntityInfo GetEntityInfo(Type type)
{
return entityInfoList.Single(e => e.Types.Contains(type));
}
private static IList<EntityInfo> GetEntityList()
{
// Builds a list of EntityInfo's...
}
}
Is the entityInfoList in class B guaranteed to be initialized and populated before B.GetEntityInfo() is called in class A?
Yes, it is guaranteed. Here's a snippet from MSDN:
The program cannot specify exactly when the class is loaded. However,
it is guaranteed to be loaded and to have its fields initialized and
its static constructor called before the class is referenced for the
first time in your program.
EDIT: As pointed out, you could end up in a situation where 2 static classes depend on each other for initialization which could get you in trouble, but as long as that's not the case, you're fine.
No, if you have circular dependencies it's possible to run code from a class before that class's static initialization has finished.
Here's a simple example of a static field initialized to 5, and yet an external class observes that field being null:
public class A
{
public static void Foo()
{
Console.WriteLine(B.bar == null);
}
}
public class B
{
public static readonly object bar = Foo();
public static object Foo()
{
A.Foo();
return 5;
}
}
private static void Main(string[] args)
{
var bar = B.bar;
}
This will print true.
I understand how in C# closures allow access to private variables declared in the same scope as an anonymous method, so that those variables are available when the method is invoked in a different scope.
But what about private constructors? This code works:
class Program
{
static void Main(string[] args)
{
var someClassFactory = SomeClass.GetFactoryMethod();
var someclass = someClassFactory();
}
}
class SomeClass
{
private SomeClass()
{
}
public static Func<SomeClass> GetFactoryMethod()
{
return () => new SomeClass();
}
}
As the compiler creates a class for the closure, how does it then reference the private constructor, or otherwise allow it to be accessed when the anonymous method is invoked by the client code?
In this case, the compiler doesn't need to create a class at all - it can just create a static method:
public static Func<SomeClass> GetFactoryMethod()
{
return __GeneratedMethod;
}
private static SomeClass __GeneratedMethod()
{
return new SomeClass();
}
Even when it does need to generate a class - e.g. if GetFactoryMethod() had a parameter which was captured by the lambda expression - it would generate a nested class, and nested classes have access to the private members of their enclosing classes:
public class Foo
{
private Foo() {}
public class Bar
{
public Foo MakeNewFoo()
{
return new Foo(); // This is absolutely fine
}
}
}
The documentation on static constructors in C# says:
A static constructor is used to
initialize any static data, or to
perform a particular action that needs
performed once only. It is called
automatically before the first
instance is created or any static
members are referenced.
That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.
Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?
To make this a bit more concrete, I thought that the code below would work:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.
Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?
If not, then... dummy member it is!
You may call static constructor explicity, so you will not have to create any methods for initialization:
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof (TypeBase).TypeHandle);
You may call it in static constructor of derived class.
As others have noted, your analysis is correct. The spec is implemented quite literally here; since no member of the base class has been invoked and no instance has been created, the static constructor of the base class is not called. I can see how that might be surprising, but it is a strict and correct implementation of the spec.
I don't have any advice for you other than "if it hurts when you do that, don't do that." I just wanted to point out that the opposite case can also bite you:
class Program
{
static void Main(string[] args)
{
D.M();
}
}
class B
{
static B() { Console.WriteLine("B"); }
public static void M() {}
}
class D: B
{
static D() { Console.WriteLine("D"); }
}
This prints "B" despite the fact that "a member of D" has been invoked. M is a member of D solely by inheritance; the CLR has no way of distinguishing whether B.M was invoked "through D" or "through B".
The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.
I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).
In all of my testing, I was only able to get a call to a dummy member on the base to cause the base to call its static constructor as illustrated:
class Base
{
static Base()
{
Console.WriteLine("Base static constructor called.");
}
internal static void Initialize() { }
}
class Derived : Base
{
static Derived()
{
Initialize(); //Removing this will cause the Base static constructor not to be executed.
Console.WriteLine("Derived static constructor called.");
}
public static void DoStaticStuff()
{
Console.WriteLine("Doing static stuff.");
}
}
class Program
{
static void Main(string[] args)
{
Derived.DoStaticStuff();
}
}
The other option was including a static read-only member in the derived typed that did the following:
private static readonly Base myBase = new Base();
This however feels like a hack (although so does the dummy member) just to get the base static constructor to be called.
I almost alway regret relying on something like this. Static methods and classes can limit you later on. If you wanted to code some special behavior for your Type class later you would be boxed in.
So here is a slight variation on your approach. It is a bit more code but it will allow you to have a custom Type defined later that lets you do custom things.
abstract class TypeBase
{
private static bool _initialized;
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new Type<int> {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
}
class Type<T> : TypeBase
{
private static Type<T> _instance;
public static Type<T> Instance
{
get
{
Initialize();
return _instance;
}
internal set { _instance = value; }
}
public string Name { get; internal set; }
}
Then later when you get to adding a virtual method to Type and want a special implementation for Type you can implement thus:
class TypeInt : Type<int>
{
public override string Foo()
{
return "Int Fooooo";
}
}
And then hook it up by changing
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new TypeInt {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
My advice would be to avoid static constructors - it is easy to do. Also avoid static classes and where possible static members. I am not saying never, just sparingly. Prefer a singleton of a class to a static.
Just an idea, you can do something like this:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
static Type()
{
new Type<object>();
}
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I have couple of question regarding Static Constructor in C#.
What exactly are Static Constructor and how they are different from non-static Constructor.
How can we use them in our application ?
**Edited
public class Test
{
// Static constructor:
static Test()
{
Console.WriteLine("Static constructor invoked.");
}
public static void TestMethod()
{
Console.WriteLine("TestMethod invoked.");
}
}
class Sample
{
static void Main()
{
Test.TestMethod();
}
}
Output :
Static constructor invoked.
TestMethod invoked.
So, this means that static constructor will be called once. if we again call Test.TestMethod(); static constructor won't invoke.
Any pointer or suggestion would be appreciated
'
Thanks
Static constructors are constructors that are executed only ONCE when the class is loaded. Regular (non-static) constructors are executed every time an object is created.
Take a look at this example:
public class A
{
public static int aStaticVal;
public int aVal;
static A() {
aStaticVal = 50;
}
public A() {
aVal = aStaticVal++;
}
}
And consider this code:
A a1 = new A();
A a2 = new A();
A a3 = new A();
Here, static constructor will be called first and only once during the execution of the program. While regular constructor will be called three times (once for each object instantiation).
static constructors are usually used to do initialization of static fields for example, assigning an initial value to static fields.. Do keep in mind that you will only be able to access static members (methods, properties and fields) on static constructors.
If you need to "execute the static constructor multiple times", you can't do that. Instead, you can put the code you want to run "multiple times" in a static method and call it whenever you need. Something like:
public class A {
public static int a, b;
static A() {
A.ResetStaticVariables();
}
public static void ResetStaticVariables() {
a = b = 0;
}
}
You use them the same way you use instance constructors - to set default values. Only in this case you'll be initializing static fields, so static constructors get executed only once.
Be aware that the code in static constructor won't be executed until the first call to the class was made.
it runs when class is loaded.
It will print :
{
hi from static A
A
}
public class A{
static A{
print("hi from static A");
}
public A() {
print("A");
}
main() {
new A();
}
}