In some languages such as VB.NET, in-line initialization of fields takes place after a base object's constructor has run. In such languages, such declarations may refer to the object under construction. In C#, however, the field initializations are done before execution of the base constructor. Because constructing a delegate would allow code to get a reference to the base object, the C# compiler won't allow such operations until after the base constructor has been invoked. It doesn't matter whether the method used by the delegate would access any virtual or base-class members, since the compiler would in general have no way of knowing whether code which received the delegate might manage to extract the Target
, cast it to the proper type, and access its members before the base-class constructor has run.
Personally, I prefer the late-initialization approach since there are many cases where a field's initial value should depend upon other fields, and far fewer where a field can be usefully initialized without having to know the values of at least some other fields or constructor parameters. Nonetheless, because C# is defined as it is, one must generally assign fields in constructors rather than with initializations, even in cases where the field will be assigned once and never rewritten.
Incidentally, if the outside world is required to use uses factory methods rather than exposed constructors to make instances of one's class, one may have such methods pass constructor parameters using ThreadStatic
variables. This is a bit icky, but can make in-line field initializations much more usable. It won't be possible to smoothly assign delegates in-line, but if a field initialization expression needs to pass a delegate to a method that must run before the base constructor, one could use a helper class and factory method to build "indirect delegates", so your initializer could use something like thing myField = methodNeedingActionOfInt(actionHelper.MakeAction<int>( (myClass it)=>it.someMethodTakingInt));
, where actionHelper
is a ThreadStatic field which is partially set up in the factory method, and finished in the base constructor, but I don't know any way to do that cleanly enough to be worthwhile.