有没有办法存储委托而不将它绑定到一个对象,就像使用MethodInfo一样?现在我正在存储一个MethodInfo,所以我可以给它调用方法的对象。但我更愿意让它成为代表。就像有一个属性告诉.net第一个参数是“this”吗?
MethodInfo mi;
Action<string> func;
mi.Invoke(this,new object[]{str});
func(this, str); //Is this possible with a delegate?
答案 0 :(得分:13)
您想要的是open instance delegate。它不直接在C#语言中支持,但CLR支持它。
基本上,开放实例委托与普通委托相同,但在正常参数之前需要this
的额外参数,并且具有空目标(如静态方法的委托)。例如,等效于Action<T>
的开放实例将是:
delegate void OpenAction<TThis, T>(TThis @this, T arg);
这是一个完整的例子:
void Main()
{
MethodInfo sayHelloMethod = typeof(Person).GetMethod("SayHello");
OpenAction<Person, string> action =
(OpenAction<Person, string>)
Delegate.CreateDelegate(
typeof(OpenAction<Person, string>),
null,
sayHelloMethod);
Person joe = new Person { Name = "Joe" };
action(joe, "Jack"); // Prints "Hello Jack, my name is Joe"
}
delegate void OpenAction<TThis, T>(TThis @this, T arg);
class Person
{
public string Name { get; set; }
public void SayHello(string name)
{
Console.WriteLine ("Hi {0}, my name is {1}", name, this.Name);
}
}
有关详细信息,请查看this article。
答案 1 :(得分:5)
您可以使用Delegate.CreateDelegate
方法为MethodInfo
创建强类型委托。
如果在编译时不知道方法的签名,可以使用Reflection创建Func<...>
,或者创建一个调用MethodInfo
的lambda表达式:
MethodInfo methodInfo = ...;
object thisObj = ...;
Func<object[]> callMethod = args => methodInfo.Invoke(thisObj, args);
(这叫做currying)
请注意,与Delegate.CreateDelegate
不同,每次调用委托时,仍然会从反射中获得性能。
答案 2 :(得分:1)
委托本质上只是一个MethodInfo
(实际上是一个MethodBase
)和一个对象引用,带有一些内部性能指针。因此,如果您有MethodInfo
,那么您基本上拥有一个未绑定的委托。您的具体用例是什么?
答案 3 :(得分:1)
为什么不简单
Action<T, string> unbound = (This, str) => This.Method(str);
所以你可以
unbound(instanceA, "hello");
unbound(instanceB, "world");
甚至
Action<string> bound = str => unbound(instanceC, str);