2016-05-18 7 views
-1

Ich habe diesen Code;Call Aktion von einer anderen Aktion

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-Klasse:

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){} 
} 

Ich möchte eine Aktion zurückkehren und wenn die Taste gedrückt wird, rufen Sie die action.But dieses nicht funktioniert? Was ist das Problem? Aktion ist ein Delegat, also Delegat ist ein Referenztyp? (Compiler generierte Klasse) Was ist falsch in diesem Bild?

Ich denke, wenn "Show()" endet, wird "Aktion" von Gargabe Sammler gesammelt. Aber das funktioniert mit anderen Referenztypen? beispielsweise;

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

Das ist gut. Weiter codieren. – ViVi

Antwort

1

Delegierte sind unveränderlich. Wenn Sie zwei Delegaten mit + = kombinieren, erstellen Sie tatsächlich eine neue Deligate. Wenn Sie also act + = ... in dem obigen Code getan haben, haben Sie tatsächlich eine neue Deligate erstellt, die sich von der unterscheidet, die Sie bereits in der "Show()" - Methode erstellt haben.

+0

Ich wusste das nicht. Meinst du "Aktion?. Invoke" referenziert nur "CallForTest" -Methode, wenn ich "_Button.OnClick" aufrufen, weil Delegaten unveränderlich sind? Also, in _button.OnClick, Aktion bezieht sich auf alte Aktion im Speicher richtig? – Cevizli

+1

Rechts. Delegierte sind unveränderlich; Einmal erstellt, ändert sich die Aufrufliste eines Delegaten nicht. Ref: https://msdn.microsoft.com/en-us/library/system.delegate(v=vs.110).aspx –

1

Ich glaube, dies geschieht, weil, wenn Sie += zu einem Delegierten verwenden sie in die interne Liste nicht anhängen. Aus diesem Grund wird b.string() nicht gedruckt

Ohne das Design zu ändern, können Sie die Aktion nicht an den ursprünglichen Delegaten anhängen, wenn auf die Schaltfläche geklickt wird.

Was Sie schreiben, tatsächlich ist ungefähr wie:

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

var act = act + act2; 

wie Sie Akt bekommt einen neuen Verweis auf die kombinierte Expression von act + act2 statt act selbst act2 intern verketten sehen können.

Wenn Sie act(false) tun, werden Sie die zusätzlichen Ergebnisse sehen, aber nicht, wenn Sie die Schaltfläche klicken klicken.

Was sollten Sie verwenden ist event auf den Delegaten in der Button, der die Art und Weise UI-Steuerelemente ist sind

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

am besten zur Verwendung von Ereignissen zu lesen, wenn Sie Multicastdelegaten auf diese Weise haben wollen . MSDN site

Verwandte Themen