2013-07-04 2 views
1

Кажется, что добавление делегата в Action, хранящееся в Dictionary, сбой при попытке добавить его через ссылку, полученную с использованием метода TryToGetValue.Ошибка при добавлении делегата в словарь действий с использованием ссылки

Вот пример воспроизведения ошибки:

void Foo() 
{ 
    Console.WriteLine("Foo"); 
} 
void Bar() 
{ 
    Console.WriteLine("Bar"); 
} 

Dictionary<int, Action> dic = new Dictionary<int, Action>();  

dic[3] = delegate{}; 
dic[3] += Foo; 

Action ac; 
if (dic.TryGetValue(3,out ac)) 
{ 
    Console.WriteLine("Found"); 
    ac += Bar; 
} 
dic[3](); 

Выход:

Found 
Foo 

значение найдено, но, кажется, что ac и dic[3] ссылки на различные объекты (Bar не печатается) ,

Может ли кто-нибудь объяснить мне, что происходит? С чем именно заполняется out parameter? Так как Action являются классами, не должно ac точка отсчета к тому же объекту, хранящемуся в Dictionary?

ответ

1

Ваш пример может быть упрощена (словарь исключен):

void Foo() { 
    Console.WriteLine("Foo"); 
    } 

    void Bar() { 
    Console.WriteLine("Bar"); 
    } 

    ... 
    Action x = Foo; 
    Action y = x; 

    if (Object.ReferenceEquals(x, y)) 
    Console.WriteLine("x was equal to y"); 

    // creates new delegate instance: 
    // x = x + Bar; 
    // that is equal to 
    // x = Action.Combine(x, Bar); 
    // so x is not equal to y any longer: 
    // x is a combined delegate (Foo + Bar) 
    // y is a delegate to Foo (an old version of x) 
    // such a behavior is typical for operators (+, +=, etc.): 
    // when we declare "public static MyType operator + (MyType a, MyType b)" 
    // it means that a new object "c" will be created that'll equal to sum of a and b 
    x += Bar; 

    if (Object.ReferenceEquals(x, y)) 
    Console.WriteLine("x is still equal to y"); 

    y(); 

Выход:

x was equal to y

Foo

И причина такого поведения в алгоритме + = операции

+0

So в основном метод Combine возвращает новое значение Action? – Heisenbug

+0

Да. Это типично для операторов (+ или + = в этом случае) –

+0

большое спасибо. Моя ошибка довольно ясна прямо сейчас. – Heisenbug

Смежные вопросы