I noticed that some code that I wrote in MSIL to get arbitrary properties of objects at high speed does not get the correct DateTime property values. It always returns the same values regardless of the actual value of the DateTime object, for example. The year always returns 1, Millisecond returns 88, etc.
LINQPad shows a piece of code that demonstrates this. Getting mc.Inner.Age returns the correct value, mc.Inner.DateOfBirth returns the correct DateTime value, but when you try to get any specific part, mc.Inner.DateOfBirth always returns the wrong value. I looked and tried a few things to make it work, but I'm not experienced enough to really know what else you can try at this point. I'm not sure if there is something inaccurate in my code, or is there something special about the DateTime object that causes this.
void Main()
{
var mc = new MyClass();
mc.FirstName = "Jane";
mc.LastName = "Doe";
mc.Inner.DateOfBirth = new DateTime(1960, 2, 13);
mc.Inner.Age = 54;
Object obj = mc;
obj = this.GetObjectProperty(obj, "Inner");
obj = this.GetObjectProperty(obj, "DateOfBirth");
obj = this.GetObjectProperty(obj, "Year");
obj.Dump();
obj = mc;
obj = obj.GetType().GetProperty("Inner").GetValue(obj);
obj = obj.GetType().GetProperty("DateOfBirth").GetValue(obj);
obj = obj.GetType().GetProperty("Year").GetValue(obj);
obj.Dump();
}
private Object GetObjectProperty(Object obj, String property)
{
var m = obj.GetType().GetMethod("get_" + property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
DynamicMethod meth = new DynamicMethod("GetObjectProperty", typeof(Object), new [] { typeof(Object) }, obj.GetType());
var il = meth.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, obj.GetType());
il.EmitCall(OpCodes.Call, m, null);
if (m.ReturnType.IsValueType)
il.Emit(OpCodes.Box, m.ReturnType);
il.Emit(OpCodes.Ret);
return ((GetObjectPropertyDelegate)meth.CreateDelegate(typeof(GetObjectPropertyDelegate), obj))();
}
private delegate Object GetObjectPropertyDelegate();
public class MyClass
{
public MyClass()
{
this.Inner = new MyInnerClass();
}
public String FirstName { get; set; }
public String LastName { get; set; }
public MyInnerClass Inner { get; set; }
}
public class MyInnerClass
{
public DateTime DateOfBirth { get; set; }
public int Age { get; set; }
}
source
share