I need something to build dynamically property retrieval methods at runtime and to execute fast, so I developed a solution using Reflection Emit
:
public static void Func(string properyName, A obj)
{
var type = obj.GetType();
var dynamicMethod = new DynamicMethod("PropertyExtractor", typeof(string), new[] { typeof(A) }, type, true);
var ilGen = dynamicMethod.GetILGenerator();
var getMethod = type.GetMethod($"get_{properyName}");
var property = type.GetProperty(properyName);
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Castclass, type);
ilGen.Emit(OpCodes.Callvirt, getMethod);
var toStringMethod = property.PropertyType.GetMethod("ToString", Type.EmptyTypes);
ilGen.Emit(OpCodes.Call, toStringMethod);
ilGen.Emit(OpCodes.Ret);
var @delegate = (F)dynamicMethod.CreateDelegate(typeof(F));
var a = @delegate(obj);
}
public delegate string F(A obj);
public abstract class A
{
public int Id { get; set; }
public string Name { get; set; }
}
public class B : A
{
public DateTime Timestamp { get; set; }
}
Here is the code to invoke it:
var obj = new B
{
Id = 1,
Name = "SomeName",
Timestamp = DateTime.Today
};
Func("Timestamp", obj);
This is just for testing that's why it is in a method named Func
with parameter of type A
, etc.
As you can see you give it the name of the property and the instance and it creates a delegate to retrieve the string value of the property in that particular instance. Everything works fine until there is a DateTime
. I test with DateTime.Now
assigned to a property and every time I run the function i get weird values like:
i tried to put a IFormatProvider just in case - same results.
.NET version is 4.7.1,
Thanks in advance.
I found the problem. DateTime is a value type and ToString requires an address to be loaded onto the evaluation stack, not a value. When I added a local variable of the time and added the instructions to store the value in the local variable and then load the address of that variable it was resolved. Thanks to everyone that responded.