问题
Using Jon Skeet's article Making reflection fly and exploring delegates as a guide, I am trying to use the Delegate.CreateDelegate method to duplicate properties as delegates. Here's an example class:
public class PropertyGetter
{
public int Prop1 {get;set;}
public string Prop2 {get;set;}
public object GetPropValue(string propertyName)
{
var property = GetType().GetProperty(propertyName).GetGetMethod();
propertyDelegate = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), this, property);
return propertyDelegate();
}
}
The problem I'm having is when I call GetPropValue
and pass in "Prop1"
as the parameter, I get an ArgumentException
on the call to Delegate.CreateDelegate
with the message "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."
This happens when using any property that returns a primitive/value type including structs.
Does anybody know a way to be able to use both reference and value types here?
回答1:
Fundamentally your general approach isn't possible. The reason you're able to take all non-value types and treat them as a Func<object>
is by relying on contravariance (Func<T>
is contravariant with respect to T
). As per the language specs, contravariance does not support value types.
Of course, the problem is easier if you just don't rely on using that approach.
If you just want to get the value use the PropertyInfo.GetValue
method:
public object GetPropValue(string name)
{
return GetType().GetProperty(name).GetValue(this);
}
If you want to return a Func<object>
which will fetch the value whenever it's called, just create a lambda around that reflection call:
public Func<object> GetPropValue2(string name)
{
return () => GetType().GetProperty(name).GetValue(this);
}
来源:https://stackoverflow.com/questions/19256233/c-sharp-using-properties-with-value-types-with-delegate-createdelegate