Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you detect if a C# field has been assigned a default value?

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.

like image 667
philsquared Avatar asked Nov 07 '08 12:11

philsquared


People also ask

How do I know if my AC is leaking Freon?

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.

Can you smell Freon leak?

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.


2 Answers

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 :-)

like image 163
chakrit Avatar answered Oct 04 '22 10:10

chakrit


You might want to consider a nullable int for this behavior:

class MyClass
{
  int? myInt = 7;
  int? myOtherInt = null;
}
like image 26
John Lemp Avatar answered Oct 04 '22 11:10

John Lemp