2016-05-18 5 views
-1

У меня есть этот код;Вызвать действие из другого действия

Button button = new Button(); 
MessageBox ms = new MessageBox(button); 

Action<bool> action = ms.Show(); 
action += (b) => 
{ 
     Console.WriteLine(b.ToString()); //this isnt working 
     Console.WriteLine("??"); 
}; 

Console.Read(); 
button.OnClick(); 
Console.ReadKey(); 

MessageBox класс:

class MessageBox 
{ 
    Button _button; 
    public MessageBox(Button button) { _button = button; }//initialize button 
    public Action<bool> Show() 
    { 
     Action<bool> action = new Action<bool>(CallForTest); 
     _button.OnClick+=()=>{ action?.Invoke(true); }; 
     return action; 
    } 
    //...working.*// 
    public void CallForTest(bool statu){} 
} 

Я хочу вернуть действие и при нажатии на кнопку, вызовите action.But это не будет работать? В чем проблема? Действие является делегатом, поэтому делегат является ссылочным типом? (Класс, сгенерированный компилятором). Что не так на этом рисунке?

Я думаю, что когда «Show()» заканчивается, «действие» собирается из коллекционера gargabe. Но это работает с другими ссылочными типами? например;

public Test Show() 
{ 
Test test = new Test("??"); 
button.OnClick +=() => 
{ 
    test.JustForTest(); //working (cw("?????" + ctorvalue); 
}; 
    return test; 
} 
+0

Это хорошо. Продолжайте кодирование. – ViVi

ответ

1

Делегаты неизменяемы. Когда вы комбинируете двух делегатов, использующих + =, вы фактически создаете новый deligate. Поэтому, когда вы сделали act + = ... в приведенном выше коде, вы создали новый deligate, он отличается от того, что вы уже создали в методе Show().

+0

Я не знал этого. Вы имеете в виду «действие? .Invoke», просто ссылающееся на метод «CallForTest», когда я вызываю «_button.OnClick», потому что делегаты неизменяемы? Итак, в _button.OnClick, действие ссылается на старые действия в памяти? – Cevizli

+1

Справа. Делегаты неизменны; после создания список вызовов делегата не изменяется. Ссылка: https://msdn.microsoft.com/en-us/library/system.delegate(v=vs.110).aspx –

1

Я считаю, что это происходит потому, что при использовании += делегата он не добавляет к внутреннему списку. Вот почему вы не видите b.string(), который печатается

Без изменения дизайна вы не сможете добавить действие к оригинальному делегату при нажатии кнопки.

То, что вы на самом деле писать это Somthing как:

var act2 = new Action<bool>((b) => 
     { 
      Console.WriteLine(b.ToString()); //this isnt working 
      Console.WriteLine("??"); 
     }); 

var act = act + act2; 

как вы можете видеть акт получает новую ссылку на комбинированную экспрессию act + act2, а не act сама конкатенации act2 внутренне.

если вы делаете act(false), вы увидите дополнительные результаты, но не при нажатии кнопки.

То, что вы должны использовать это event на делегат в Баттона, который контролирует способ пользовательского интерфейса написаны

class Button 
{ 
    public event EventHandler<BoolEventArgs> Click; 
} 

лучше прочитать об использовании событий, когда вы хотите иметь многоадресных делегатов на этом пути , MSDN site

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