【问题标题】:Delegate is a pointer to a function? And also saves variables?委托是指向函数的指针?并且还保存变量?
【发布时间】:2012-05-22 18:29:16
【问题描述】:

据我了解委托的概念,它们只是指向一个方法。然后当我感到幸运时,我可以出去调用我的委托所指向的方法,对吗?

给出以下代码:

class Program
{
    static void Main(string[] args)
    {
        Func<MyClass> myAct = GetAct();

        Method(myAct);
    }

    private static Func<MyClass> GetAct()
    {
        MyClass obj = new MyClass()
        {
            Prop1 = 5
        };

        Func<MyClass> myAct = new Func<MyClass>(
            () =>
            {
                MyClass obj2 = new MyClass();
                MyClass2 obj3 = new MyClass2()
                {
                    Prop3 = 25,
                    Prop4 = "test"
                };

                obj2.Prop2 = ((obj.Prop1 + 5) * obj3.Prop3)
                    .ToString() + obj3.Prop4;

                return obj2;
            });
        return myAct;
    }

    static void Method(Delegate func)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();

        var result = func.DynamicInvoke();
    }
}

class MyClass
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
}

class MyClass2
{
    public int Prop3 { get; set; }
    public string Prop4 { get; set; }
}

现在我的委托myAct(在本例中为Func&lt;MyClass&gt;)指向一个匿名函数,该函数执行一些简单的变量分配。到目前为止没有什么特别的。

我们调用委托。

一切顺利,正如我们预期的那样。但问题是为什么?如果委托只是简单地指向匿名方法并且垃圾回收已经完成,CLR 怎么知道obj 和它的值是什么? obj 的引用存储在哪里,以便在调用函数时可用?在委托内部?

【问题讨论】:

  • 我认为主要问题是委托“仅指向方法”的基本假设过于简单化。事实上,一个委托实例可以持有对多个方法的引用...
  • 还要注意使用闭包的陷阱:msmvps.com/blogs/peterritchie/archive/2010/11/03/…
  • @JamesMichaelHare 在这种情况下它只是指向一个方法。该方法恰好位于捕获当前范围的编译器生成的匿名类中,但它仍然是一个方法。多播代表完全是另一个问题。
  • @ChrisShain:我同意它们是一个不同的问题,我只是指出将它们视为指向方法的简单指针并不十分准确。

标签: c# delegates parameter-passing


【解决方案1】:

您的匿名方法在GetAct()作用域 内定义,因此CLR 使作用域 变量可用于匿名方法。

这类似于实例变量如何被成员方法使用。

另外,回顾一下使用闭包的陷阱:http://msmvps.com/blogs/peterritchie/archive/2010/11/03/deep-dive-on-closure-pitfals.aspx

【讨论】:

  • 应该可能会在答案中加入“关闭”这个词,因为搜索它是我了解该主题的最佳方式。
  • @Servy 评论被盗并被合并。 =p
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
相关资源
最近更新 更多