我有一个使用匿名类型的实例调用的方法。类型始终相同,但实例不同。
注意:我只是将匿名对象作为对象
类型传递。
我知道匿名类型有一个名为 Request
且类型为 HttpRequestMessage
的属性。这是我的方法,它是使用 info.Value
中的匿名类型执行的。
void IObserver<KeyValuePair<string, object> event> OnNext(KeyValuePair<string, object> info)
{
HttpRequestMessage request = ?????
}
我可以像这样获取属性 getter:
MethodInfo propertyGetter = type.GetProperty("Request").GetGetMethod();
但是在读取传递给我的实例的属性时,我无法承受反射的成本。
如何创建一个委托(delegate),将实例传递给该委托(delegate)并获取属性值?
我试过了
private delegate HttpRequestMessage RequestPropertyGetterDelegate(object instance);
private static RequestPropertyGetterDelegate RequestPropertyGetter;
private static RequestPropertyGetterDelegate CreateRequestFromPropertyDelegate(Type type)
{
MethodInfo propertyGetter = type.GetProperty("Request").GetGetMethod();
return (RequestPropertyGetterDelegate)Delegate.CreateDelegate(typeof(RequestPropertyGetterDelegate), propertyGetter);
}
但是我遇到了绑定(bind)错误
System.ArgumentException: 'Cannot bind to the target method because its signature is not compatible with that of the delegate type.'
最佳答案
就是这样,使用表达式树。
您所要做的就是缓存getter
,性能应该与直接访问相同。
void Main()
{
var instance = new TestClass { Request = "Something 2" };
var getter = CreateRequestFromPropertyDelegate(typeof(TestClass));
// Cache getter per type
var value = getter(instance);
Console.WriteLine(value); // Prints "Something 2"
}
private delegate string RequestPropertyGetterDelegate(object instance);
static RequestPropertyGetterDelegate CreateRequestFromPropertyDelegate(Type type)
{
// Entry of the delegate
var instanceParam = Expression.Parameter(typeof(object), "instance");
// Cast the instance from "object" to the correct type
var instanceExpr = Expression.TypeAs(instanceParam, type);
// Get the property's value
var property = type.GetProperty("Request");
var propertyExpr = Expression.Property(instanceExpr, property);
// Create delegate
var lambda = Expression.Lambda<RequestPropertyGetterDelegate>(propertyExpr, instanceParam);
return lambda.Compile();
}
class TestClass
{
// Using string here because I'm on LINQPad
public string Request { get; set; }
}
关于c# - 如何创建委托(delegate)来读取匿名类型的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65551984/