First, a general note: you speak of "the value" as though you could get it from analyzing the IL. This isn't true in general, because the expression could be anything, as long as it doesn't involve this
. You can only get the instructions that calculate the value, which may be enough for your application. For an edge case, consider the fact that in particular, the expression may initialize fields other than the backing field of the property:
public int i { get; set; } = s = t = 1;
public static int s { get; set; } = t;
public static int t = 2;
The semantics of this are predictable but not obvious: the default value of s
is 0 (t
has not been explicitly initialized at this point because initialization happens in declaration order), the default value of t
is 2, and the default value of i
is 1, with the twist that its initialization, if it occurs, also sets t
and then s
to 1. Deriving the values from the IL code in this case is not trivial, and even identifying the initializers requires that you consider which stfld
/stsfld
instructions assign to property backing fields, as opposed to any old field.
Speaking of trivial, if a property is initialized to the default value of the type, the compiler may elide generation of the property initialization altogether since it will be handled by newobj
. On the IL level, the following may result in the same code:
int a { get; set; } = 3 / 4;
and
int a { get; set; }
This is an edge case in the sense that what looks like an initializer in code may not be present in the IL at all. If all you're interested in is the value, not whether an explicit initializer was used, this is of course no problem.