C# 作为引用传递时的委托行为

C# 作为引用传递时的委托行为,c#,C#,我正在和代表们玩游戏,我不知道发生了什么 在我的逻辑中,“问候语”委托的调用列表应该返回2,但它只返回1。如您所见,我正在将委托引用传递给我创建的对象。我想确认委托可以从外部引用私有方法,唯一的要求是在将方法分配给委托的过程中可以访问该方法 class Program { static void Main(string[] args) { Action greetings = FirstGreeting;

我正在和代表们玩游戏,我不知道发生了什么

在我的逻辑中,“问候语”委托的调用列表应该返回2,但它只返回1。如您所见,我正在将委托引用传递给我创建的对象。我想确认委托可以从外部引用私有方法,唯一的要求是在将方法分配给委托的过程中可以访问该方法

    class Program
    {
        static void Main(string[] args)
        {
            Action greetings = FirstGreeting;

            Test test = new Test();
            test.AddGreeting(greetings);

            Console.WriteLine(greetings.GetInvocationList().Count());

            greetings();

            Console.ReadLine();
        }

        static void FirstGreeting()
        {
            Console.WriteLine("This is the first greeting.");
        }
    }

    class Test
    {
        public void AddGreeting(Action greetings)
        {
            greetings += new Action(SecondGreeting);
        }

        private void SecondGreeting()
        {
            Console.WriteLine("This is the second greeting.");
        }
    }
如您所见,我正在将委托引用传递给我创建的对象

是的,但您正在使用:

greetings += new Action(SecondGreeting);
这将创建一个新的委托-它不会更改现有委托。委托是不可变的,就像字符串一样。如果您真的希望代码按预期的方式工作,则必须使用:

public void AddGreeting(ref Action greetings)
{
    greetings += new Action(SecondGreeting);
}
并称之为

test.AddGreeting(ref greetings);
(或返回对新代理的引用,如Peter的回答所示。)

有关
+=
功能的更多详细信息,请参阅my

如您所见,我正在将委托引用传递给我创建的对象

是的,但您正在使用:

greetings += new Action(SecondGreeting);
这将创建一个新的委托-它不会更改现有委托。委托是不可变的,就像字符串一样。如果您真的希望代码按预期的方式工作,则必须使用:

public void AddGreeting(ref Action greetings)
{
    greetings += new Action(SecondGreeting);
}
并称之为

test.AddGreeting(ref greetings);
(或返回对新代理的引用,如Peter的回答所示。)


有关
+=
功能的更多详细信息,请参见my。

我刚刚尝试了您的代码,可以理解您的意思。如果您在
AddGreeting()
方法中添加一行,在该点上打印出调用列表,您将在其中看到两个方法。但是正如Jon Skeet所指出的,委托是不可变的,您没有返回创建的新(多播)委托

我建议您将方法更改为:

public Action AddGreeting(Action greetings)
{
    return greetings + new Action(SecondGreeting);
}

因为这将为您提供正确的调用集。

我刚刚尝试了您的代码,可以理解您的意思。如果您在
AddGreeting()
方法中添加一行,在该点上打印出调用列表,您将在其中看到两个方法。但是正如Jon Skeet所指出的,委托是不可变的,您没有返回创建的新(多播)委托

我建议您将方法更改为:

public Action AddGreeting(Action greetings)
{
    return greetings + new Action(SecondGreeting);
}

这将为您提供正确的调用集。

是的,这是通过引用传递的替代方法。是的,这是通过引用传递的替代方法。