Guarantee static fields exist before referenced in static field initializer - c#

Problem:
Class1.foo1 relies on Class2.foo2, but it can't be guaranteed they'll compile in an order that will allow class2.foo2 to have been initialized when referenced by Class1.foo1.
class Class1
{
static Foo foo1 = new Foo("arg1", Class2.foo2);
}
class Class2
{
static Foo foo2 = new Foo("arg2");
}
Since Class2.foo2 has not be initialized when Class1.foo1 is created, the 'Class2.foo2' argument passed is simply null.
My Question:
Is there a known pattern to handle this sort of reliance scenario that doesn't require verbose initializers to be written for every field? I can throw as much code into the Foo class as needed to make it work because it only runs once at the beginning of the program, I'd just really like to keep it hidden away, because a great number of these fields need to be written.
What I've Read:
I've come across a few threads talking about lazy initialization which almost sounds appropriate in that it does something the first time an object is needed, and it's field specific, but it results in unwieldy code:
static Foo _otherFoo;
static Foo otherFoo
{
get
{
if (_otherFoo == null)
return new Foo("arg2");
else return _otherFoo;
}
}
I'd like to save my fellow developers from carpal tunnel. It wouldn't be a problem if all this bloat could be hidden behind a constructor:
public Foo(params Foo[] dependencies)
{
if(anyItem in dependencies) == null
anyItem = new Foo("Params are defined per-instance in the initializer. What goes here?");
}
But I can't know Class2.foo2's initialization parameters. Since this only runs once at startup, I decided to look into reflection as an option, but from what I've seen, reflection can't help you discern anything about a field's initializer, you can only get its value after it's been initialized.
It looks like the order of class initialization is determined by the order fields are accessed:
Is the order of static class initialization in C# deterministic?
So I ran some tests to see how this plays out, and it doesn't seem to halt initialization of fields in order to intialize their dependencies i.e. Class1.foo1's constructor must fully complete before Class2.foo2 gets initialized, which means Class2.foo2 will remain null.
My Question (again):
Is there a known pattern to handle this sort of reliance scenario that doesn't require verbose initializers to be written for every field?

Related

.NET: Determine whether object is partially or fully constructed

Is there any way to query the .NET runtime to determine whether an object has finished its construction, or if the construction is still on-going and/or was aborted with an exception?
Basically, something equivalent to:
class Foo {
public string ConstructionState { get; private set; }
public Foo() {
try {
ConstructionState = "ongoing";
// ... do actual constructor stuff here ...
ConstructionState = "completed";
}
catch (Exception) {
ConstructionState = "aborted";
throw;
}
}
}
... except also taking into account field initializers, base class constructors etc., and without needing to modify the constructor.
A well-behaved object should never expose itself until it's fully constructed. If a partially constructed object is leaked, you're already violating that contract.
The runtime doesn't care, of course. There's nothing special about a partially-constructed object as far as the runtime is concerned - it's still subject to the same memory constraints, finalization and garbage collection as a fully constructed object.
If you own the object, the solution is simple - don't leak the object during construction. The usual way to do some global change during object initialisation is to use a static method (or a factory) instead of a constructor. If you don't own the object, you're pretty much out of luck.
The runtime specification doesn't explicitly say there's no way to check if an object is partially constructed, but it doesn't say there is either (as far as I can tell) - so even if you found some way, it wouldn't be safe to rely on it. Inspecting by hand shows that .NET object headers have no such information, and a disassembly of the constructor shows there's no non-user code after a constructor finishes that could update such a state.
The runtime does store a few flags in "weird" places. The mark & sweep garbage collector in desktop MS.NET stores its marks in an "unused" bit of the pointer to the virtual method table, for example. But as far as the runtime is concerned, the object is "done" even before any of its constructors run - all of that is handled during the allocation in newobj, before the constructor (a special instance method) runs. The object header (which also contains the object size) and virtual method table (so the object is of the most derived type even before the constructors run) are already set here, and all the memory directly used by that instance is already allocated (and pre-zeroed - so you don't get pointers to random bits of memory). This means that memory safety isn't impacted by partially-constructed objects as far as the runtime is concerned.
The main difference between a constructor and another instance method is that the constructor must only ever be called once on any instance. On the CIL level, this is enforced simply by the fact that you can't invoke the constructor directly - you only ever use newobj, which pushes the constructed object on the stack. Just like with other instance methods, it doesn't track if a particular method finishes or not - after all, it's perfectly legal to have a method that never finishes, and you can actually do the same thing with a (non-static) constructor.
If you want a proof that the runtime doesn't care, I present to you... the object can be collected by the GC before the constructor even finishes:
class Test
{
public static WeakReference<Test> someInstance;
public static void AliveTest()
{
Test t;
if (someInstance == null) Console.WriteLine("Null");
else Console.WriteLine(someInstance.TryGetTarget(out t));
}
public Test()
{
someInstance = new WeakReference<Test>(this);
AliveTest();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
AliveTest();
}
}
class Program
{
static void Main(string[] args)
{
Test t = new Test();
Test.AliveTest();
Console.ReadLine();
}
}
This test program writes out True, False, False (make sure to run it in Release mode and without the debugger - .NET prevents many things like this to make debugging easier). The object has been collected before its constructor even finished, which means that there's no special treatment for constructors in this regard. Another reason not to use the "constructor updates something static" pattern, and especially not the "finalizer updates it back". If you add a finalizer to this sample code, it will run before the constructor finishes. Ouch.
Even your solution would be insufficient in the general case. To cite CLI specification:
It is explicitly not a requirement that a conforming implementation of the CLI guarantee that all state updates performed within a constructor be uniformly visible before the constructor completes.
There's no guarantee another thread would have correct information about the construction state.
For bonus points, it also doesn't help if the object isn't sealed. A derived classes constructor would run after the base class constructor and in C# there's no way to rewrite this to encompass all the constructors that normally run in a sequence. The best you could do is maintain a separate "constructed state" for each constructor, which is confusing at best (and breaks a few OOP principles - it would require all consumers of the object to know of all possible types the object could have).

Static variable population best practice

I have a class Meterage which I expect to be instantiated several times, probably in quick succession. Each class will need to know the location of the dropbox folder in the executing machine, and I have code for this.
The class currently has a variable:
private string dropboxPath = string.Empty;
to hold the path, but I am considering making this a static to save repeated execution of
this.LocateDropboxFolder();
in the constructor. But I am a little concerned by the switch: what if two constructors try to set this at the same time? Would this code in the constructor be safe (LocateDropboxFolder becomes static too in this example):
public Meterage()
{
if (dropboxPath == string.Empty)
{
LocateDropboxFolder();
}
}
I think my concerns are perhaps irrelevant as long as I don't have construction occurring in multiple threads?
If the field is made static then static field initializers or static constructors are the easy way to initialize them. This will be executed at most once in a thread safe manner.
private static string dropboxPath;
static Meterage()
{
LocateDropboxFolder();
}
If you don't want to re-assign the field I suggest you to use readonly modifier, then the code should look like:
private static readonly string dropboxPath;
static Meterage()
{
dropboxPath = LocateDropboxFolder();
}
LocateDropboxFolder needs to return a string in this case.
Variables declared outside the constructor are evaluated before the constructor. Then the constructor will evaluate it.
Do remember that you will end up have only one dropBoxPath. If this is intended, it is okay to do so. Optionally, make LocateDropboxFolder a static method and call it from the static constructor.
If you want to prevent other constructors to overwrite the default, try this:
if (string.IsNullOrEmpty(dropboxPath))
{
LocateDropboxFolder();
}
Or, in a static constructor (at most called once):
static Meterage()
{
LocateDropboxFolder();
}
private static LocateDropboxFolder()
{
...
}
Your example will be safe provided your code is executing synchronously. If multiple instances are created, their constructors will be called in the order they are created.
On the first run through, LocateDropboxFolder() will execute. When this completes, dropboxPath will be set.
On the second constructor execution, LocateDropboxFolder() will not execute because dropboxPath will no longer equal string.Empty (provided 'LocateDropboxFolder()' does not return string.Empty.
However, if LocateDropboxFolder() is asynchronous or the objects are instantiated on different threads, then it is possible to create a second Meterage instance before dropBoxPath has been set by the LocateDropboxFolder() function. As such, multiple calls to the function will likely be made.
If you wish to guard against multithreading errors like this, you could consider using lock statements.
You might potentially end up running the LocateDropboxFolder multiple times if the object tries to be constructed multiple times in close succession from multiple threads. As long as the method returns the same result every time though this shouldn't be a problem since it will still be using the same value.
Additionally if you are setting the value of dropboxPath in the constructor then there is no point setting a default value for it. I'd just declare it (and not assign it) and then check for null in your constructor.
I hava a feeling that your Meterage class is breaking a Single Responsibility Principle. What has the meterage to do with a file access? I would say you have 2 concerns here: your Meterage and, let's say, FolderLocator. the second one should have some property or method like Dropbox which could use lazy evaluation pattern. It should be instantiated once and this single instance can be injected to each Metarage instance.
Maybe not FolderLocator but FileSystem with some more methods than just a single property? Nos sure what you're actually doing. Anyway - make an interface for this. That would allow unit testing without using the actual Dropbox folder.

Is non-trivial constructor in IoC paradigm a bad thing?

I'm using dependency injection in my C# projects and generally everything is ok.
Nevertheless, I often hear the rule "constructor must only consist of trivial operations - assign dependencies and do nothing more" I.e:
//dependencies
interface IMyFooDependency
{
string GetBuzz();
int DoOtherStuff();
}
interface IMyBarDependency
{
void CrunchMe();
}
//consumer
class MyNiceConsumer
{
private readonly IMyFooDependency foo;
private readonly IMyBarDependency bar;
private /*readonly*/ string buzz;//<---question here
MyNiceConsumer(IMyFooDependency foo, IMyBarDependency bar)
{
//omitting null checks
this.foo = foo;
this.bar = bar;
//OR
this.buzz = foo.GetBuzz();//is this a bad thing to do?
}
}
UPD: assume IMyFooDependency can't be replaced with the GetBuzz(), as in that case the answer is obvious: "do not depend on foo".
UPD2: Please, understand that this question is not about eliminating dependency from foo in a hypothetic code, but about understanding a principle of good constructor design.
So, my questions is following: is this really a bad pattern to include non-trivial logic in constructor(i.e. obtaining buzz value, making some calculations based on dependencies.)
Personally I, unless lazy load is necessary, would include foo.GetBuzz() in constructor, as object need to be initialized after call to its constructor.
The only drawback I see: by including non-trivial logic you increase the number of places where something might go wrong, and you'll get an obfuscated error message from your IoC container(but same things happen in case of invalid parameter, so the drawback is rather minor)
Any other considerations for eliding non-trivial constructors?
If you need IMyFooDependency only for buzz creation, then you actually need buzz:
class MyNiceConsumer
{
private readonly IMyBarDependency bar;
private readonly string buzz;
MyNiceConsumer(string buzz, IMyBarDependency bar)
{
this.buzz = buzz;
this.bar = bar;
}
}
And create instance of nice consumer this way:
new MyNiceConsumer(foo.GetBuzz(), bar);
I don't see any difference between obtaining buzz before passing parameters to constructor, or obtaining it inside constructor. Same value will be returned from repository. So, you don't need to depend on repository.
UPDATE: Technically there is nothing wrong with complex initialization logic in constructor. Take a look on winforms InitializeComponent method, where all controls are created, initialized and added to form.
But it violates SRP (creation and initialization) and its hard to test. You can read more about this flaw on writing testable code guide. Main idea:
Do not create collaborators in your constructor, but pass them in.
(Don’t look for things! Ask for things!)
The rationale for not doing any work in the constructor comes from looking at the execution of the program in two phases. The first phase is to wire up your object graph. The second phase is to do the "real work".
There is a tension between this ideal and efficiently maintaining a class's invariants and internal state. The less setup you can do in your constructor, the more difficult all of your methods will be to implement because they must take into account the varying possible internal state of the object. Remember, the constructor is the only code you can be sure is called for an object.
The way out of this conundrum is to realize that an object's "real work" is defined by it's interface and behavior in relation to other objects. That is, the dependencies provided to the constructor and objects provided as arguments to methods later down the road.
Feel free to do any kind of setup you like in your constructor that does not have a noticeable effect on other objects in your system. Likewise, be very sensitive to timing issues in your object's construction.
If you determine that a File object can't exist without a filename provided by the user: don't call keyboard.filename_from_keyboard() in the constructor. Instead you design your system such that the object is created by a factory (provider) during execution with the filename provided to the constructor or you allow the File object to exist without a filename. Maybe it can get it's own filename during execution? This is part of managing your object's lifetime and it's the hardest part IMO. This gets very subtle because "real work" involves creating objects too. But I digress...
In your example you would have to decide if foo.GetBuzz() breaks that condition. If GetBuzz() is a referentially transparent function, you're almost always in the clear to call it in the constructor. If GetBuzz() involves any I/O, user interaction or changes any noticeable internal state of any other object, then it is probably does not need to be called from a constructor.
As lazyberezovsky rightly mentioned, don't look for things! Ask for things!
If the creating code (let's say, MyNiceCreator) treats foo as an opaque value and news up MyNiceConsumer, then most likely creation should not be the responsibility of MyNiceCreator. The code that creates the MyNiceConsumer instance must be able to give the required values to the constructor.
A better pattern:
MyNiceCreator should "ask" for a MyNiceConsumer instance. This way the creation of MyNiceConsumer instance will be the responsibility of the appropriate class.

C# static garbage collector?

I have a simple class which has a static constructor and a instance constructor. Now when i initialized the class , both static and instance constructor are called. Only static is referred once in a application domain . Can i again call the same class initialization and static constructor initialize again? I have tried but it didn't happen? Is there any way we can call static constructor again in main() method after using garbage collection on the class.
Here is the code:
public class Employee
{
public Employee()
{
Console.WriteLine("Instance constructor called");
}
static Employee()
{
Console.WriteLine("Static constructor called");
}
~Employee()
{
//Dispose();
}
}
Now in main method call:
static void Main(string[] args)
{
Employee emp = new Employee();
Employee emp = new Employee();
}
Output:
Static constructor called
Instance constructor called
Instance constructor called
Now the static didn't called again. Because it is called once in application domain. But is their any way we could call it again without unloading application domain. Can we use GC class over here?
Thanks.
Pal
Unless you prod it with reflection, the static constructor (or more generally, the type initializer) is only executed once per concrete class, per AppDomain.
Note that for generics, using different type arguments you'll get different concrete classes:
public class Foo<T>
{
Foo()
{
Console.WriteLine("T={0}", typeof(T));
}
public static void DummyMethod() {}
}
...
Foo<int>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Type is already initialized; no more output
Not possible. The CLR keeps an internal status bit that tracks whether the type initializer was started. It cannot run again. That status bit is indeed stored in the loader heap as part of the AppDomain state. The workaround is simple, just add a static method to the class.
The point of a constructor is to put things into a desired initial valid state.
An instance constructor puts an instance into an initial valid state.
An instance constructor that takes arguments puts an instance into a initial valid state that reflects its arguments.
A static constructor puts the type into an initial valid state. E.g. initialising static members used by the class' static methods or shared by all instances.
Ideally all methods will leave the object and the type in a valid state, but constructors differ in being responsible for getting it into one in the first place.
Any attempt to call a constructor twice is therefore a mistake, since "put it into an initial valid state again" isn't something you can logically do twice ("initial" and "again" don't work well in the same clause). We are helped by the compiler (in it refusing to compile) and the language (in there being no way to express this) from doing such a thing.
And, being a logical impossibility it isn't something you can actually want to do (well, I can want to draw a triangle with more than 3 sides, but only to say that I did). This suggests that you are using your constructor to do something other than setting up an initial valid state.
Doing anything other than establishing such a valid state in a constructor is (as is failing to do so) at best an optimisation, quite often a serious design flaw and quite possibly (worse of all because it goes unfixed longer) an attempted optimisation that is really a serious design flaw.
One sign that your attempt at an optimisation is really a design flaw is a desire to call a static constructor more than once, or to call an instance constructor more than once on the same object.
Identify the desired repeatable behaviour, move it into a separate method, and have it called as needed from both the constructor and elsewhere. Then double check your design's logic, as this is quite a serious mistake to find in a class design and suggests you've got deeper problems.

Is a class instantiated when a static method is called in a non-static class?

Exactly what happens when Foo.SomeCheck() is called in the Bar class? Is an instance of Foo created in order to call SomeCheck()? If so, is this instance stored on the heap, and is it ever collected through garbage collection?
public class Foo() {
public static bool SomeCheck() {
return true;
}
}
public class Bar() {
public void SomeMethod() {
// what happens when we access Foo to call SomeCheck?
if (Foo.SomeCheck()) {
//do something
}
}
}
Static methods differ from instance methods in that no instance of the class they belong to needs to have been created for them to be called. When you call a static method, you in fact make the call using the name of the type rather than an instance of the type - which should reinforce the idea that static methods are not called on instances. That bears repeating and emphasis: No instance of a class is required to call a public static method of that class.
Now, your example is malformed, but presumably, the line: if( Foo.SomeCheck() ) is calling the SomeCheck static method using the name of the type: Foo - not an instance. Bar however, has to be instantiated in order to make this call - however, in your example, you don't have a well-formed instance of Bar. Code generally has to exist inside a method (or a member initializer) - which you don't have here.
To respond to the other parts of your question. Assuming the code in question is part of an instance method, something has to instantiate Bar - and invoke that method. That something would have to create or otherwise acquire an instance of Bar. Reference types will always be creted on the heap - but that's largely irrelevant here.
As for garbage collection, you normally shouldn't worry about this. The .NET runtime makes sure to cleanup instances that are not referenced from any root object in your program. Roots are typically instances that reside somewhere on the callstack or are referenced by static members of one type or another. Since we don't see any code here that creates or references Bar it's impossible to say when it will be collected. For instance, if Bar is a singleton and stored somewhere in a static variable, it may live for a very long time - perhaps the entire lifetime of the program. You can't really know without seeing all of the code that manipulates and manages Bar.
I highly recommend reading the following article:
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
It explains how the .NET runtime works at a low level, and explains internal nuances like Loader Heaps and how static classes/members work. Technically speaking, there IS an initial instantiation of the 'static instnace' of a classes static members. However, this initiation is handled by the runtime in a different way than it is handled for class instances. Static classes are stored on loader heaps, which are not GC managed. Loader heaps are allocated and grown in a static manner, and are not compacted. The article is a great read, and should give you a thourough understanding of how the CLR operates.
(NOTE: I am not certain of how valid this article is for .NET 4. I do know that there were GC changes in .NET 4, however I am not sure how many fundamental runtime changes there are. The introduction of the DLR and other features may deviate from the explanation in the above article to some degree.)
Foo does not need to be instantiated, neither will it get instantied upon the SomeCheck static method call as per result, you would get the value returned by the method itself, and not an instance of the class.
Please have a look at these references for further details:
Static vs Non-Static Methods;
Static Classes and Static Class Members (C# Programming Guide).
I do hope this helps! =)
It depends on the implementation of SomeMethod. The method will have to be invoked from somewhere, presumably a "driver" class which would instantiate Bar and call SomeMethod. For example:
public class Driver
{
public static void Main()
{
Bar bar = new Bar();
bar.SomeMethod();
}
}
Given your current implementation of SomeMethod, yes, you'd have to instantiate it.
However, as long as SomeMethod only makes a call to another static method, we could make make it static too. In which case you wouldn't have to create an instance of Bar to invoke the method. i.e.
public class Driver
{
public static void Main()
{
Bar.SomeMethod();
}
}
public class Manipulate
{
public static int Main(string[] args) {
Bar bar = new Bar();
bar.BarFoo();
Console.ReadKey();
return 0;
}
}
public class Foo {
public static bool SomeCheck() {
return true;
}
}
public class Bar {
// what happens when we access Foo to call SomeCheck?
public void BarFoo() {
if (Foo.SomeCheck()) {
Console.WriteLine("Hello am true");
}
}
}
Yes you need to create an instance of Bar but not for Foo class since it is a static metod. Only difference is, the static methods are called at class level(compile time) rather than object level(run time), so you don't need to instantiate the Foo class.

Categories