在作为参考传递时委派行为

时间:2012-04-07 08:11:46

标签: c#

我和代表一起玩,我遇到的情况是我不知道发生了什么。

在我的逻辑中,“greetings”委托的调用列表应该返回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.");
        }
    }

2 个答案:

答案 0 :(得分:3)

  

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

是的,但您正在使用:

greetings += new Action(SecondGreeting);

这会创建一个 new 委托 - 它不会更改现有的委托。代表是不可变的,就像字符串一样。如果您真的希望代码以您期望的方式工作,则必须使用:

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

并将其命名为

test.AddGreeting(ref greetings);

(或者返回对新代表的引用,如Peter的回答所示。)

有关+=所做的更多详情,请参阅我的article on delegates and events

答案 1 :(得分:1)

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

我建议你改变你的方法:

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

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