C#委托没有绑定到实例?

Wil*_*ill 10 c#

有没有办法存储委托而不将它绑定到一个对象,就像你可以使用MethodInfo一样?现在我正在存储一个MethodInfo,所以我可以给它调用方法的对象.但我更愿意让它成为代表.就像有一个属性告诉.net第一个参数是"this"吗?

MethodInfo mi;
Action<string> func;
mi.Invoke(this,new object[]{str});
func(this, str); //Is this possible with a delegate?
Run Code Online (Sandbox Code Playgroud)

Tho*_*que 14

你想要什么称为开放实例委托.它不直接在C#语言中支持,但CLR支持它.

基本上,开放实例委托与普通委托相同,但它this在普通参数之前需要额外的参数,并且具有空目标(如静态方法的委托).例如,相当于open的实例Action<T>将是:

delegate void OpenAction<TThis, T>(TThis @this, T arg);
Run Code Online (Sandbox Code Playgroud)

这是一个完整的例子:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请查看此文章.


SLa*_*aks 5

您可以使用该Delegate.CreateDelegate方法为a创建强类型委托MethodInfo.

如果在编译时不知道方法的签名,可以创建一个Func<...>使用Reflection,或者创建一个调用以下内容的lambda表达式MethodInfo:

MethodInfo methodInfo = ...;
object thisObj = ...;
Func<object[]> callMethod = args => methodInfo.Invoke(thisObj, args);
Run Code Online (Sandbox Code Playgroud)

(这称为currying)

请注意,每次调用委托时,这仍然会从反射中获得性能,而不像Delegate.CreateDelegate.