问题 代表们指出了什么?


我已经读过,引用类型包含对可以存储在托管堆上的实际对象的引用。当一个方法被“赋值”给一个委托引用变量时,该引用指向哪个内存?这个内存块与实际的功能代码有什么关系?


6678
2018-02-25 03:48


起源

不完全是您正在寻找的答案,但这篇文章可能会提供一些有关代表的见解 stackoverflow.com/questions/527489/... - Bala R


答案:


让我们分开一个简单的例子:

using System;
class Program
{
    delegate bool MyFilter(int x);

    bool IsOdd(int x)
    {
        return x % 2 == 1;
    }

    static void Main()
    {
        MyFilter f = new Program().IsOdd;
        Console.WriteLine(f(5));
    }
}

编译器做什么?让我们从这一行开始:

delegate bool MyFilter(int x);

编译器生成一个 类型 看起来有点像这样:

class MyFilter : MulticastDelegate
{
    public MyFilter(Object thisRef, IntPtr method);
    public bool Invoke(int x);
    // BeginInvoke(), EndInvoke() - Let's ignore those
}    

MyFilter类型有一个构造函数,它接受两个参数:一个要调用的方法体的IntPtr,以及一个应该调用此方法的Object。 MyFilter类型的Invoke()方法调用实际的委托。

现在,让我们看看Main()方法中发生了什么。编译器会像这样重写它:

    static void Main()
    {
        MyFilter f = new MyFilter(new Program(), addressof(Program.IsOdd));
        Console.WriteLine(f.Invoke(5));
    }

当然,addressof不是一个真正的C#操作符,但你可以想象它返回传入方法的主体地址。另外,我没有讨论与代理相关的各种其他主题,例如链接(这是MulticastDelegate基类提供的功能),但希望我已经解决了你的问题。

总而言之,委托引用指向一个实现与委托签名匹配的Invoke方法的对象。该对象跟踪指向需要调用的方法的指针,以及调用该方法的目标对象(除非该方法是静态的)。


14
2018-02-25 04:23





实际上有两种委托类型, 代表 和 MulticastDelegate。这些是从a的实际实例继承的抽象类 delegate。我建议阅读这些课程,因为他们有比我在这里解释的更多(准确)细节,但对于短版本:

虽然我不是百分之百确定实现的确切方式,但最简单的方法是思考 Delegate 对象正在举行 object,和 MethodInfo,这是特定方法的反射类型。原因是 Delegate 类型是抽象的,是因为 Invoke 方法取决于方法的参数。

同样的, MulticastDelegate 持有多个 Delegate 对象,每个对象指向一个人 object/MethodInfo 组合。这允许 event 系统,单身 event 被激活会导致调用多个方法。

回到实现细节,当您定义委托时,它会从中创建一个继承的类 MulticastDelegate 与 Invoke 方法,也是 object 可 null 对于静态方法。

除此之外,你还有具体的方法 MulticastDelegate 对象在调用之间传递,但我可能已经在这篇文章中犯了一些错误,所以我会留下它。


0
2018-02-25 04:10





在没有给出过于复杂的答案的情况下,它指向(引用)存储方法的实际存储块。


0
2018-02-25 04:16





委托实际上包含两个地址 - 方法的地址以及对象的地址。这非常有趣,与代表们有关的几项专利被授予Heljsberg http://www.google.com/patents/US6185728

它非常有效。在一个 访问,Heljsberg指出它比VTBL dispatch更有效(因为它是一个直接指向函数的指针)。在最简单的情况下,它实际上是间接调用。例如

 jmp *%eax

总的来说,它需要 执行委托的4条指令


0
2018-02-25 10:34