题
在阅读以下问题之后,我正在挖掘一些差异: delegate.createdelegate()和仿制药:错误绑定到目标方法
我从巴里·凯利(Barry Kelly)找到了一些非常好的代码https://www.blogger.com/comment.g?blogid=8184237816669520763&postID=2109708553230166434
这里是(以加糖的形式:-)
using System;
namespace ConsoleApplication4
{
internal class Base
{
}
internal class Derived : Base
{
}
internal delegate void baseClassDelegate(Base b);
internal delegate void derivedClassDelegate(Derived d);
internal class App
{
private static void Foo1(Base b)
{
Console.WriteLine("Foo 1");
}
private static void Foo2(Derived b)
{
Console.WriteLine("Foo 2");
}
private static T CastDelegate<T>(Delegate src)
where T : class
{
return (T) (object) Delegate.CreateDelegate(
typeof (T),
src.Target,
src.Method,
true); // throw on fail
}
private static void Main()
{
baseClassDelegate a = Foo1; // works fine
derivedClassDelegate b = Foo2; // works fine
b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though
b(new Derived());
b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection
b(new Derived());
}
}
}
除了这条线(看起来很简单)外,我都了解所有这些。
b = a.invoke; //使用方差分配委派的简便方法,虽然增加间接层
谁能告诉我:
- 如何在不传递静态函数所需的参数的情况下调用Invoke。
- 当您从调用Invoke分配返回值时,何时在引擎盖下进行
- 巴里通过额外的间接意味着什么(在他的评论中)
解决方案
他没有打电话 Invoke
(请注意缺乏 ()
),他正在使用隐式代表创建来设置 b
等于新的 derivedClassDelegate
指向的实例 Invoke
的方法 a
. 。其他间接是什么时候 b
被调用,调用 a.Invoke(new Derived())
而不是只是 a(new Derived())
.
使实际发生的事情更加明确:
baseClassDelegate a = Foo1; // works fine
derivedClassDelegate b = Foo2; // works fine
b = new derivedClassDelegate(a.Invoke); // the easy way to assign delegate using variance, adds layer of indirection though
b(new Derived());
b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection
b(new Derived());
第一次打电话给 b
结果产生这样的链(为简单起见,消除了参数):
b() -> a.Invoke() -> Foo1()
第二个电话 b
结果:
b() -> Foo1()
然而
仅当您需要一个签名的代表来调用另一个(限制性较小)签名的代表时,才需要这一点。在他的示例中,您可以设置 b = Foo1
它会编译,但这并不能说明这一点。
不隶属于 StackOverflow