C# 底层委托问题
在阅读 SO 中的以下问题后,我正在深入研究委托方差: 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.调用; // 使用方差分配委托的简单方法,增加了间接层,但
谁能告诉我:
- 如何在不传递静态函数所需的参数的情况下调用调用。
- 当您分配调用调用的返回值时,什么时候会发生
- Barry 的额外间接含义是什么(在他的评论中)
I was doing some digging around into delegate variance after reading the following question in SO : Delegate.CreateDelegate() and generics: Error binding to target method
I found a very nice bit of code from Barry kelly at
https://www.blogger.com/comment.g?blogID=8184237816669520763&postID=2109708553230166434
Here it is (in a sugared-up form :-)
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());
}
}
}
I understand all of it except this one (what looks very simple) line.
b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though
Can anyone tell me:
- how it is possible to call invoke without passing the param required by the static function.
- When is going on under the hood when you assign the return value from calling invoke
- What does Barry mean by extra indirection (in his comment)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
他没有调用
Invoke
(请注意缺少()
),而是使用隐式委托创建将b
设置为等于新的>衍生类代理
实例,指向a
的Invoke
方法。额外的间接是,当调用b
时,它会调用a.Invoke(new Derived())
而不仅仅是a(new Derived())
代码>.为了使实际发生的情况更加明确:
第一次调用
b
会产生这样的链(为简单起见,省略了参数):第二次调用
b
会产生这样的结果:<然而,
仅当您需要一个签名的委托来调用另一个(限制较少的)签名的委托时,才需要这样做。在他的示例中,您只需设置 b = Foo1 即可编译,但这并不能说明问题。
He isn't calling
Invoke
(note the lack of()
), he's using implicit delegate creation to setb
equal to a newderivedClassDelegate
instance that points to theInvoke
method ofa
. The additional indirection is that whenb
is invoked, it callsa.Invoke(new Derived())
rather than justa(new Derived())
.To make what's actually happening more explicit:
The first call to
b
results in a chain like this (parameters eliminated for simplicity):The second call to
b
results in this:However
This is only needed if you need a delegate of one signature to invoke a delegate of another (less restrictive) signature. In his example, you could just set
b = Foo1
and it would compile, but that wouldn't illustrate the point.