I have a static container class that holds a handle to some class A:
public static class Container
{
private static A _a;
public static void Register(A a) { _a = a; }
public static void Run() { _a.DoIt(); }
}
Registration of the container A instance is performed in the A constructor:
public class A
{
public A() { Container.Register(this); }
public void DoIt() { Console.WriteLine("Running!"); }
}
Now, let's say that I register my A instance by calling a method that only contains an A instantiation:
public void Init() { var a = new A(); }
Theoretically, could compilation be optimized to ignore this assignment, or can I be 100% sure that A is always instantiated when I call the Init method?
Example When I run the following code:
Init();
...
Container.Run();
will Container._a always be defined and the output from the DoIt method written to the console?
The compiler doesn't in general know if the constructor of A has observable side-effects, so it will always call it. It may not keep the variable 'a' around though.
So, the constructor will be called, but the result may not be assigned to the variable; instead the A object may just be immediately registered for garbage collection if nothing else references it. (In your case, something else DOES reference it - namely, the Container class - so it WON'T be garbage-collected!)
In your case, the constructor manifestly DOES have side-effects in any case (so it would be a major error for the compiler to optimise away the constructor call).
In summary:
The constructor will always be called.
The assignment of the result to the local variable may not be done because the compiler knows that it has no observable side-effects.
In your code, something else retains a reference to the constructed object, so it won't be GCed.
Related
I'm trying to use the AutoMapper for model-viewmodel mapping and wanted to have the mapping configuration executed once in the static constructor of the type. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type.
My understanding is that the Mapper.Map would try to access the type, its members through reflection and on the first attempt of the usage the static constructor would be called. This is something basic but challenges my understanding. The code snippet is provided.
class SampleViewModel
{
static SampleViewModel()
{
Mapper.Initialize(cfg => cfg.CreateMap<Sample, SampleViewModel>().ReverseMap());
}
public SampleViewModel()
{
}
public int PropertyA { get; set; }
public int PropertyB { get; set; }
}
Sample s = new Sample { PropertyA = 10, PropertyB = 20 };
var obj = Mapper.Map<SampleViewModel>(s); // fails
Isn't the static constructor called (if provided) when the type and members are accessed through reflection for the first time?
You're not accessing any members of SampleViewModel - it's not enough to just reference the type itself.
Mapper.Map only accesses its own internal "dictionary" of mappings - before it could ever get to a point where it deals with a SampleViewModel, it fails. The static constructor never runs, so it cannot add "itself" into the Mapper.
Now, if this didn't involve reflection, you would be right that the static constructor would be called - simply because it would happen during the compilation of the method containing the access, e.g.:
var obj = Mapper.Map<SampleViewModel>(s);
Console.WriteLine(obj.SomeField);
In this case, since the method is referencing a field on SampleViewModel, the static constructor for SampleViewModel will be invoked during JIT compilation of the containing method, and as such, the Mapper.Map<SampleViewModel>(s) line will execute correctly, since the mapping is now present. Needless to say this is not the proper solution to your problem. It would just make the code absolutely horrible to maintain :)
DISCLAIMER: Even though this might fix the problem right now, it depends on a non-contractual behaviour in the current implementation of MS.NET on Windows. The contract specifies that the type initializer is invoked before any access to a member of the type, but that still means that a valid implementation of CIL might only call the type initializer after Mapper.Map, as long as it happens before obj.SomeField - and even then, it might be that obj.SomeField gets optimized away if the compiler can ensure it is safe to do so. The only real way to enforce the call of the type initializer is to call RuntimeHelpers.RunClassConstructor, but by that point, you could just as well add a static Init method or something.
The real problem is that you shouldn't really initialize stuff like this in a static constructor in the first place. Mappings should be set in some kind of deterministic initialization process, say, an explicitly invoked InitMappings method. Otherwise you're opening yourself to a huge can of Heisenbugs, not to mention subtle changes in the CLR breaking your whole application for no apparent reason.
Static constructors just aren't meant for "registration", just the initialization of the type itself - anything else is an abuse, and will cause you (or the .NET compatibility team) trouble.
Static constructors run at an implementation-defined time just before the first instance of that class is created, or before any static member of that type is accessed. See When is a static constructor called in C#?.
The mapper tries to find a mapping before doing its work of instantiating the class to map into, and thus can't find a mapping, because the class was never instantiated before that moment.
Just move your mapping initialization code into a AutoMapperBootstrap.cs file or something, and call that in your application initialization.
".. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type..."
I tested your scenario and observed that the static constructor is indeed being called before the first instance of the object is created.
C# Programming Guide: Static Constructors
I also went ahead and modified the sample code by adding a GetMapper function which returns an IMapper. This might seem like an overkill for day-to-day simple mapping, but if we need an object to give us its mapper, perhaps we can get it from a static method.
One can easily move the responsibility of creating the Mapper object to a factory or a DI container which, for the sake of simplicity, I did not include here.
Worth noting that in this example, the static fields are initialized before the static constructor which is called right after the static read-only fields are initialized.
Uses AutoMapper v12.0 and .Net Core 3.1.
public class SimpleObjectToMap
{
private static readonly MapperConfiguration _simpleObjMapperConfig = new MapperConfiguration(
config => config.CreateMap<SimpleObjectToMap, ObjectToBeMappedTo>());
private static readonly IMapper _mapper = new Mapper(_simpleObjMapperConfig);
private int _propertyA;
public int PropertyA
{
get
{
Console.WriteLine("ObjectToMap.PropertyA.Get");
return _propertyA;
}
set { _propertyA = value; }
}
static SimpleObjectToMap()
{
Console.WriteLine("*** ObjectToMap static ctor called ***");
}
public static IMapper GetMapper()
{
return _mapper;
}
}
public class ObjectToBeMappedTo
{
static ObjectToBeMappedTo()
{
Console.WriteLine("*** ObjectToBeMappedTo static ctor called ***");
}
private int _propertyA;
public int PropertyA
{
get { return _propertyA; }
set
{
Console.WriteLine("ObjectToBeMappedTo.PropertyA.Set");
_propertyA = value;
}
}
}
public class TestObjectMappingWithStaticCtor
{
public void TestWithStaticCtor()
{
SimpleObjectToMap objToMap = new SimpleObjectToMap { PropertyA = 27 };
var mappedObject = SimpleObjectToMap.GetMapper().Map<ObjectToBeMappedTo>(objToMap);
}
}
In the following code segment, I reference FILE_LOCATION from outside this class, and after execution flows into this class to access that constant, for some reason instead of continuing back to the location where the constant call was made, execution continues to instantiate the singleton.
My question is two parts; why is this happening and how can I work around it? I tried to create two partial classes, one solely for the constant and another for everything else, but execution still continued to the other partial class to instantiate the singleton.
public sealed class Foo
{
public static readonly string FILE_LOCATION = #"path\to\file";
// (singleton code modeled after:
// http://csharpindepth.com/articles/general/singleton.aspx --fourth version)
private static readonly Foo foo = new Foo();
// Rest of class implementation...
}
The property is referenced from an instance of a form class on a button click:
public partial class MyForm : Form
{
public void button1_Click(object sender, EventArgs e)
{
string s = Foo.FILE_LOCATION;
// this location is only reached AFTER the singleton is instantiated.
}
}
To answer your questions in order,
This occurs because C# guarantees that all static variables get initialized before you can access any individual static variable. When you call a static variable, accessing FILE_LOCATION, then all the static variable initializers run (including foo). After that, the static constructor runs. Since there is no explicit static constructor, nothing is done here. Then your code runs. The reason this occurs is that sometimes the value of a static variable might be initialized depending on another static variable, so it's required to initialize them all at the same time.
To work around this, instead of using public static readonly string FILE_LOCATION you can declare it as public const string FILE_LOCATION. The value of a const is determined at compile-time and not at run-time, and so the static variable foo will not be initialized when you access the FILE_LOCATION. This can work if you can determine the value of the file location at compile-time; is that something you can do in your application?
I have a job interview tomorrow and I'm trying to answer this question:
There is a class named C and method m in this class, this class have also empty constructor:
Main ()
{
C c = new c();
}
Class C {
public c {
//empty constructor
}
public m {
//does something - doesnt mind
}
}
And what you have to do is to change the code so that in a creation of an instance class C, the method m would be called before the class constructor.
You have to do this without changing the main (edit only the class code).
Thanks in advance!
Like the other answers have said, you can make the method static. But then you need to explicitly call it. If you make a static class constructor, that will get called once automatically (you don't need to call it), the first time the class is referenced (like when you construct the first instance). You can't exactly control when it executes, but it will execute before the first instance is constructed. Based on the way they've worded the question (you can't change the Main method), I think static class constructor is the answer they're looking for.
http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=vs.80%29.aspx
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are
referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.
Java doesn't have static class constructors, but they do have static initialization blocks..
static {
// code in here
}
To call a class's method before its constructor gets called you either have to turn this method into static so you don't need an instance of that class to call it, or (in C#) you can use FormatterServices.GetUninitializedObject Method to get an instance of your class without running the constructor (which of course may not be a wise thing to do).
In JAVA:
make method static and call your method in static block.
class C{
static{
m();
}
public C() {
System.out.println("Constructor Called..");
}
public static void m() {
System.out.println("m() is called.");
}
}
Main call
public static void main(String[] args) {
new C();
}
In both Java and C# you can use, base class constructors, static constructors (Edit: static initializer block in Java), and field initializers, to call code before the C class's constructor executes without modifying Main.
An example using a field initializer block in Java:
class C {
{ m(); }
public C() {
System.out.println("cons");
}
public void m() {
System.out.println("m");
}
}
This prints "m", then "cons". Note that m is called every time a C is constructed. A static initializer block would only be called once for the JVM.
Its basic OOP. You have to make a public static method and call it. That method can then call the constructor, or you can call the constructor directly from main.
Before you call the constructor, the object don't exist, therefore no instance methods exist, therefore nothing tied to the instance/object can be called. The only things that do exist before the constructor is called is the static methods.
Following way seems to achieve what is required. Without using static methods/variables
namespace FnCallBeforeConstructor
{
static void Main(string[] args)
{
MyClass s = new MyClass();
Console.ReadKey();
}
partial class MyClass: Master
{
public override void Func()
{
Console.WriteLine("I am a function");
}
public MyClass()
: base()
{
Console.WriteLine("I am a constructor");
}
}
class Master
{
public virtual void Func() { Console.WriteLine("Not called"); }
public Master()
{
Func();
}
}
}
Output is:
I am a function
I am a constructor
Another question on SO inspired me to try this code in C#:
class Program
{
static Program()
{
new Program().Run();
}
static void Main(string[] args) { }
void Run()
{
System.Console.WriteLine("Running");
}
}
This prints "Running" when run.
I actually expected the compiler to complain about this. After all, if the class has not yet been initialized by the static constructor; how can we be sure that it is valid to call methods on it ?
So why does the compiler not restrict us from doing this ? Is there any important usage scenarios for this ?
Edit
I am aware of the Singleton pattern; the point in question is why I can call a method on the instance before my static constructor finishes. So far JaredPar's answer has some good reasoning about this.
It is allowed because not allowing it would be a lot worse. Code like this would deadlock badly:
class A {
public static readonly A a;
public static readonly B b;
static A() {
b = new B();
a = B.a;
}
}
class B {
public static readonly A a;
public static readonly B b;
static B() {
a = new A();
b = A.b;
}
}
You are of course pointing a loaded gun at your foot.
This behavior is documented in the CLI Spec (Ecma 335) Partition II, Chapter 10.5.3.2 "Relaxed guarantees":
A type can be marked with the attribute beforefieldinit (§10.1.6) to indicate that the guarantees specified in §10.5.3.1 are not necessarily required. In particular, the final requirement above need not be provided: the type initializer need not be executed before a static method is called or referenced.
[Rationale: When code can be executed in multiple application domains it becomes particularly expensive to ensure this final guarantee. At the same time, examination of large bodies of managed code have shown that this final guarantee is rarely required, since type initializers are almost always simple methods for initializing
static fields. Leaving it up to the CIL generator (and hence, possibly, to the programmer) to decide whether this guarantee is required therefore provides efficiency when it is desired at the cost of consistency guarantees.
end rationale]
The C# compiler indeed emits the beforefieldinit attribute on a class:
.class private auto ansi beforefieldinit ConsoleApplication2.Program
extends [mscorlib]System.Object
{
// etc...
}
Slightly different question.
How would the compiler prevent you from doing this?
Sure it's very easy to detect in your sample, but what about this sample?
class Program {
static void Fun() {
new Program();
}
static Program() {
Fun();
}
}
The ways in which you can trick the compiler to allow this are virtually endless. Even if the compiler got all of the answers you could still beat it with reflection.
In the end though this is actually legal, if a bit dangerous, code in both C# and IL. It is safe to do this as long as you are careful about accessing static's from within this code. It also is helpful / possibly necessary for certain patterns like Singleton's
Static constructor can initialize only static class members, this is not related to class instances and regular non-static class members.
What you may not realize is that for every class that does not have a non-static constructor, the compiler will generate one. This is different from your static constructor, which when you boil it down into MSIL is little more than a flag telling the CLR "Hey, run this code before you run what's in main()". So, the code of your static constructor is executed first. It instantiates a locally-scoped Program object using the NON-static constructor generated behind the scenes, and once instantiated, Run() is called on the object. Then, because you haven't stored this new object anywhere, it is disposed of when the constructor finishes executing. The main() function then runs (and does nothing).
Try this expansion:
class Program
{
static Program()
{
new Program().Run();
}
public Program()
{
Console.WriteLine("Instantiating a Program");
}
public override void Finalize()
{
Console.WriteLine("Finalizing a Program");
}
static void Main(string[] args) { Console.WriteLine("main() called"); }
void Run()
{
System.Console.WriteLine("Running");
}
}
See what the output is. My guess is that it will look something like this:
Instantiating a Program
Running
Finalizing a Program
main() called
The last two lines may be swapped because garbage collection may not get the chance to destroy the instance before main starts running (GC runs in a seperate managed thread, and so it works on its own time within the lifetime of the process), but the instance IS local to the static constructor in scope, and so is marked for collection before main() starts running. So, if you called Thread.Sleep(1000) in main() before printing the message, GC should collect the object in that time.
How does C#, or other languages for that matter, handle memory allocation (and memory de-allocation) between these two scenarios:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.load();
}
public static Loader {
public static Foo load() {
return new Foo();
}
}
2.) A method is invoked on an instance, which then falls out of scope.
public Program {
Foo foo = new Loader().load();
}
public Loader {
public Foo load() {
return new Foo();
}
}
I suppose the static class is loaded, and remains, in memory; whereas the class instance succumbs to garbage collection at C#'s leisure. Are there any pros or cons to these two paradigms? Is there ever a time when you have a class that never needs to be instantiated (i.e. some sort of resource loader or factory), but you use the second methodology anyway to take advantage of garbage collection?
The important part of my question is whether or not the first paradigm, while being conceptually correct in some circumstances, may suffer from holding on to memory unnecessarily.
Your second example doesn't work, so let's explore the real options:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public static Loader {
public static Foo Load() {
return new Foo();
}
}
2.) A static method in a non-static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public Loader {
public static Foo Load() {
return new Foo();
}
}
3.) An instance method is invoked on an instance
public Program {
Foo foo = new Loader().Load();
}
public Loader {
public Foo Load() {
return new Foo();
}
}
The two first are the same. Calling a static method is the same regardless if the class is static or not.
The third option will create an instance of the class on the heap. As the class has no data members, it will only be something like 16 bytes. It will be garbage collected eventually, but due to the small size it doesn't matter much when that happens.
Calling an instance method is also slightly different from a static method. A reference to the class instance is sent along, that you can access through the this keyword. It makes little difference in this case as there is no real data in the object to access.
The second form creates a temporary Loader object (which is very cheap). You will always have to load the Loader class, no matter which approach you choose.
There is very little performance (memory saving) to gain here. You would normally choose for a static member in a static class if there is no 'state' needed outside the methods local vars.
A static method, field, property, or event is callable on a class even when no instance of the class has been created.
http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx
So in that sense your static methods behaves just as it would if you used it from within a class instance: it is scoped to the type.
I cannot find any sources for this, but from my knowledge of programming, when you refernce a class(non static), it's structure is loaded into memory
Creating an instance of a class just to call a method, would waste a lot of processing power(due to creating an instance, assigning it memory, and the garbage collecting).
Instead of keeping the definition, and then on top of it, an instance. Why not just keep the definition(static).
As long as you don't store any data in static variables, your static method should take up the same amount of memory as your non static method definition. But using a static method, only the method will be kept in memory and be ready to be called whenever you need without creating instances. Where as, if the method is non static, it will need to be instantiated(using up memory and processing power) and the garbage collected(freeing memory and using up cpu) therefore it is definitely better using a static member. Thats what they are there for.