Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

c# - CreateDelegate with unknown types

I am trying to create Delegate for reading/writing properties of unknown type of class at runtime.

I have a generic class Main<T> and a method which looks like this:

Delegate.CreateDelegate(typeof(Func<T, object>), get)

where get is a MethodInfo of the property that should be read. The problem is that when the property returns int (I guess this happens for value types) the above code throws ArgumentException because the method cannot be bound. In case of string it works well.

To solve the problem I changed the code so that corresponding Delegate type is generated by using MakeGenericType. So now the code is:

Type func = typeof(Func<,>);
Type generic = func.MakeGenericType(typeof(T), get.ReturnType);
var result = Delegate.CreateDelegate(generic, get)

The problem now is that the created delegate instance of generic so I have to use DynamicInvoke which would be as slow as using pure reflection to read the field.

So my question is why is that the first snippet of code fails with value types. According to MSDN it should work as it says that

The return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate

and how to execute the delegate in the second snippet so that it is faster than reflection.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's one way to solve your problem. Create a generic method:

public static Func<T, object> MakeDelegate<U>(MethodInfo @get)
{
    var f = (Func<T, U>)Delegate.CreateDelegate(typeof(Func<T, U>), @get);
    return t => f(t);
}

This way, C#'s compiler takes care of inserting the necessary boxing (if any) to convert f(t) (of type U) to object. Now you can use reflection to call this MakeDelegate method with U set to @get.ReturnType, and what you get back will be a Func<T, object> which can be called without needing to resort to using DynamicInvoke.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...