Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 委托是指向函数的指针吗?还保存变量?_C#_Delegates_Parameter Passing - Fatal编程技术网

C# 委托是指向函数的指针吗?还保存变量?

C# 委托是指向函数的指针吗?还保存变量?,c#,delegates,parameter-passing,C#,Delegates,Parameter Passing,就我所理解的委托的概念而言,它们只是指向一个方法。然后,当我感到幸运时,我可以出去调用我的委托所指向的方法,对吗 给出了以下代码: class Program { static void Main(string[] args) { Func<MyClass> myAct = GetAct(); Method(myAct); } private static Func<MyClass> GetAct()

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

给出了以下代码:

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; }
}
类程序
{
静态void Main(字符串[]参数)
{
Func myAct=GetAct();
方法(myAct);
}
私有静态函数GetAct()
{
MyClass obj=新的MyClass()
{
Prop1=5
};
Func myAct=新函数(
() =>
{
MyClass obj2=新的MyClass();
MyClass2 obj3=新的MyClass2()
{
Prop3=25,
Prop4=“测试”
};
obj2.Prop2=((obj.Prop1+5)*obj3.Prop3)
.ToString()+obj3.Prop4;
返回obj2;
});
返回myAct;
}
静态无效方法(委托函数)
{
GC.Collect();
GC.WaitForPendingFinalizers();
var result=func.DynamicInvoke();
}
}
类MyClass
{
公共int Prop1{get;set;}
公共字符串Prop2{get;set;}
}
类别MyClass2
{
公共int Prop3{get;set;}
公共字符串Prop4{get;set;}
}
现在,我的委托
myAct
(在本例中为
Func
)指向一个匿名函数,该函数执行一些简单的变量赋值。到目前为止没有什么特别的

我们调用委托

一切都很顺利,正如我们所预料的那样。但问题是为什么?如果委托只是简单地指向匿名方法并完成了垃圾收集,那么CLR如何知道什么是
obj
及其值?
调用函数时,
obj
的引用存储在哪里?在委托内部?

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

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


另外,请查看使用闭包的陷阱:

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

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


另外,回顾一下使用闭包的陷阱:

请参见:我认为主要的问题是委托“简单地指向一个方法”的基本假设过于简单。事实上,一个委托实例可以包含对多个方法的引用……还要注意使用闭包的陷阱:@JamesMichaelHare在本例中,它只指向一个方法。该方法恰好位于捕获当前作用域的编译器生成的匿名类中,但它仍然是一个方法。多播委托完全是另一个问题。@ChrisShain:我同意它们是另一个问题,我只是指出,将它们视为指向方法的简单指针并不十分准确。请参阅:我认为主要问题是委托“简单指向方法”的基本假设过于简单。事实上,一个委托实例可以包含对多个方法的引用……还要注意使用闭包的陷阱:@JamesMichaelHare在本例中,它只指向一个方法。该方法恰好位于捕获当前作用域的编译器生成的匿名类中,但它仍然是一个方法。多播委托完全是另一个问题。@ChrisShain:我同意它们是另一个问题,我只是指出,将它们视为指向方法的简单指针并不十分准确。可能应该在答案中加上“闭包”一词,因为对我来说,搜索这个主题的信息是最好的方式。@Servy Comment被盗并合并=p可能应该在答案中加上“结束”一词,因为搜索这个主题是我获取该主题信息的最佳方式。@Servy Comment被盗并合并=P