CreateDelegate On Extension Method
I have a class with an IList readonly property. I have created a simple extension method, AddCSV, to add multiple items to that list. I want to create an action delegate to populate the list via the extension method. So far, I have
private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
var list = typeof(TListPropertyContainer).GetProperty(listName);
var method = typeof(Extensions).GetMethod("AddCSV");
return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}
but obviously this isn't working!
I am aware 开发者_开发问答that there are other options. For example a) I could inherit the list into my own customer class and add the AddCSV there b) I could make items property read/write and set a fully populated list into my class
I'd be grateful if someone could correct me.
Many thx
Simon
There are two main problems.
You are trying to invoke the method on a
PropertyInfo
, not a list. To get the value of the property you would need to make a call toGetValue()
The call to
GetMethod()
doesn't specify binding flags. I suspect it might work better withGetMethod("AddCSV", BindingFlags.Public | BindingFlags.Static)
.
That being said, why are you instantiating it reflectively when you know the type and the method beforehand? It seems like you could just do:
private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
var propertyInfo = typeof(TListPropertyContainer).GetProperty(listName);
return (container,value) => {
var list = (IList<TDataValue>)propertyInfo.GetValue(container,null);
list.AddCSV(list);
};
}
If I am making incorrect assumptions about the signature of the extension method or the type of property, you can still do it with Delegate.CreateDelegate()
, but take the comments about the PropertyInfo
and the BindingFlags
into account
You're trying to use list
as the target of the delegate - but list
is of type PropertyInfo
, which sounds like it's not what you were expecting. Assuming you want to get the value of the property, and then call the method on that, you'll need to pass in the object containing the property as well, so you can get the actual list. (Alternatively, maybe it's "this" - you haven't really made that clear.) Either way, you can get the list itself and use that as the target. For example:
private Action<TListPropertyContainer, TDataValue>
CreateListPropertySetter<TListPropertyContainer, TDataValue>
(string listName, object target)
{
var listProperty = typeof(TListPropertyContainer).GetProperty(listName);
object list = listProperty.GetValue(target, null);
var method = typeof(Extensions).GetMethod("AddCSV");
return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(
typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}
If this doesn't help, please edit your question with a short but complete console app demonstrating the problem. Right now there are too many unknowns to definitely help you.
精彩评论