Say you have a class declaration, e.g.:
class MyClass
{
int myInt=7;
int myOtherInt;
}
Now, is there a way in generic code, using reflection (or any other means, for that matter), that I can deduce that myInt has a default value assigned, whereas myOtherInt does not? Note the difference between being initialised with an explicit default value, and being left to it's implicit default value (myOtherInt will be initialised to 0, by default).
From my own research it looks like there is no way to do this - but I thought I'd ask here before giving up.
[Edit]
Even with nullable and reference types I want to distingush between those that have been left as null, and those that have been explicitly initialised to null. This is so that I can say that fields with an initialiser are "optional" and other fields are "mandatory". At the moment I'm having to do this using attributes - which niggles me with their redundancy of information in this case.
A technician can detect a refrigerant leak by using ultraviolet (UV) dye. An HVAC technician will send a fluorescent dye through your system to find the source of the leak. Once it circulates throughout your HVAC system, a detection lamp is used to find the leak's exact location.
Freon usually travels through closed copper coils in an AC unit, but these coils can crack and result in an AC coolant leak. A freon leak will produce a smell between sweet and chloroform. Freon leaks can be toxic.
I compiled your code and load it up in ILDASM and got this
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: ret
} // end of method MyClass::.ctor
Note the ldc.i4.7
and stfld int32 dummyCSharp.MyClass::myInt
seems to be instructions to set the default values for the myInt field.
So such assignment is actually compiled as an additional assignment statement in a constructor.
To detect such assignment, then you will need reflection to reflect on the IL of MyClass's constructor method and look for stfld
(set fields?) commands.
EDIT: If I add some assignment into the constructor explicitly:
class MyClass
{
public int myInt = 7;
public int myOtherInt;
public MyClass()
{
myOtherInt = 8;
}
}
When I load it up in ILDASM, I got this:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 24 (0x18)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: ldc.i4.8
IL_0011: stfld int32 dummyCSharp.MyClass::myOtherInt
IL_0016: nop
IL_0017: ret
} // end of method MyClass::.ctor
Note that the extra assigment on myOtherInt that I added was addded after a call the Object class's constructor.
IL_0008: call instance void [mscorlib]System.Object::.ctor()
So there you have it,
Any assignment done before the call to Object class's constructor in IL is a default value assignment.
Anything following it is a statement inside the class's actual constructor code.
More extensive test should be done though.
p.s. that was fun :-)
You might want to consider a nullable int for this behavior:
class MyClass
{
int? myInt = 7;
int? myOtherInt = null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With