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



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

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

对于后者,Delegate的目标是new Object(),而前者具有null目标。

但是,如果没有预定义的target,我如何实例化ToString方法引用的Delegate?在这种情况下,我希望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通过引用任意对象的实例方法提供了此功能。我如何在.Net中实现同样的功能?


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

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

然而,这会导致调用ToString实例方法的进一步间接性,因此,我不认为此解决方法是解决我的问题的有效方法。

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

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

最新更新