如何获得具有动态绑定目标的实例方法的方法引用

时间:2016-05-30 12:39:10

标签: c# c#-4.0 lambda delegates

在C#中,我们可以通过对静态方法或实例方法的方法引用来实例化Delegate。例如:

Func<object, object, bool> refEquals = Object.ReferenceEquals;  // target = null
Func<string> toStr = new Object().ToString; // target = new Object()

对于后者,代表的目标是new Object(),而前者的目标是null

但是,如何在没有预定义ToString的情况下为target方法引用实例化委托?在这种情况下,我希望ToString的目标将绑定到Delegate的参数。例如,这可以用于将某个实例方法调用IEnumerable<T>的所有项:

Func<object, string> toStr = Object.ToString; // the target (this) would be the Func’s argument
IEnumerable<T> dataSrc = ...
IEnumerable<String> dataSrc = dataSrc.Select(toStr);

但是,第一行不编译:

  

错误CS0123:'ToString'没有重载匹配委托'System.Func'

Java 8通过Reference to an Instance Method of an Arbitrary Object提供此功能。如何在.Net中实现同样的功能?

我知道我们可以用lambda表达式超越这个限制,例如:

 Func<Object, String> toStr = item => item.ToString();

但是,这会导致进一步间接调用ToString实例方法,因此我不会将此解决方法视为我问题的有效解决方案。

1 个答案:

答案 0 :(得分:2)

通过 Reflection ,您可以获得与Java 8中描述的行为相同的行为。您可以创建具有null目标的Delegate实例,并将其第一个参数动态绑定到this方法参数。对于您的示例,您可以通过以下方式创建toStr委托:

MethodInfo methodToStr = typeof(object).GetMethod("ToString");
Func<Object, String> toStr = (Func<Object, String>) Delegate.CreateDelegate(
            typeof(Func<Object, String>),
            methodToStr);