2012-03-25 3 views
0

Ich brauche so zu Fall des privaten Feld der Klasse befestigen:Wie "Ereignis" von privatem Feld "retrow"?

MyClass myInstance = ... 
... 
myInstance.checkbook.RangeMissing += new EventHandler<RangeMissingEventArgs>(RangeMissing); 

zu tun, dass ich checkbook public zu tun haben. Aber ich möchte checkbook private behalten, ich möchte nur "RangeMissing" -Ereignis fangen.

Also brauche ich Art von "retrow" in MyClass-Klasse von Event RangeMissing?

Natürlich kann ich das "explizit" tun (MyClass an Checkbook anschließen, RangeMissing-Ereignis abfangen, neues RangeMissing-Ereignis auslösen), aber ich denke, es ist zu kompliziert.

Habe ich ein Designproblem? Soll ich checkbook öffentlich machen? Sollte ich nur 10 Zeilen zusätzlichen Code schreiben und das Ereignis nur explizit in der Klasse MyClass erneut auslösen?

+0

Sie sollten 'checkbook' Feld ausblenden und erstellen Sie ein neues Ereignis innerhalb' MyClass' namens 'RangeMissing'. Dann in "MyClass" register für "checkbook.RangeMissing" Benachrichtigung und rufe 'this.RangeMissing (etc.)' in der Handhabung auf. –

+7

Wir werfen keine Ereignisse, wir erheben sie. –

+0

Ich denke, dass Sie diese zehn Zeilen für Kapselungen Sake hinzufügen sollten. Auf diese Weise wird RangeMissing zum Ereignis Ihrer Klasse und niemand anders weiß (und sollte nicht wissen), was gefeuert wurde. –

Antwort

2

Ich glaube, Sie haben zwei Möglichkeiten:

  1. Als Tigran vorgeschlagen, behandeln Sie das Ereignis in der Klasse durch ein anderes Ereignis auslöst:

    class MyClass 
    { 
        public event EventHandler<RangeMissingEventArgs> CheckbookRangeMissing = 
         delegate { }; 
    
        public MyClass() 
        { 
         // initialize checkbook 
    
         checkbook.RangeMissing += OnCheckbookRangeMissing; 
        } 
    
        private void OnCheckbookRangeMissing(object sender, EventArgs e) 
        { 
         CheckbookRangeMissing(this, e) 
        } 
    } 
    

    mit diesem Ansatz Seien Sie vorsichtig, denn es könnte Speicherlecks verursachen, wenn die Lebensdauer von checkbook länger ist als von MyClass. In diesem Fall müssen Sie sich von dem Ereignis abmelden, wenn Sie mit MyClass fertig sind (wahrscheinlich in einer Dispose() Methode).

  2. ein Ereignis, das alle Teilnehmer der Veranstaltung auf checkbook leitet:

    class MyClass 
    { 
        public event EventHandler<RangeMissingEventArgs> CheckbookRangeMissing 
        { 
         add 
         { 
          checkbook.RangeMissing += value; 
         } 
         remove 
         { 
          checkbook.RangeMissing -= value; 
         } 
        } 
    } 
    
+0

Um # 1 ohne Speicherverlust zu erreichen, würdest du wahrscheinlich ein benutzerdefiniertes Ereignis und zählen Sie die Anzahl der verbleibenden Handler in der 'remove' Implementierung. Dies unterscheidet sich von Option 2 darin, dass Sie immer noch den Wrapper 'sender' ersetzen. Beachten Sie auch, dass Option # 2 das 'private' Checkbook-Objekt über das' sender'-Argument an alle Abonnenten leckt. –

+0

Ist auch keine 'Null'-Prüfung erforderlich? –

+0

Sie haben Recht, ich habe einen 'Null' Check vergessen. Ich vermeide es, den 'delegate {}' "Trick" zu benutzen. – svick

1

Sie haben keine Designprobleme, noch sind diese von der Post aus sichtbar. Die einfachste und mehr streightforward Lösung, imo würde, sein

  • erste Urlaub checkbox als Privat
  • und innen MyClass Reraise ein Ereignis ausgelöst von checkbox

Auf diese Weise werden Sie Verstecken Sie ein Kontrollkästchen und legen Sie ein Ereignis Ihrem MyClass Verbraucher zur Verfügung. Außerdem können Sie, falls erforderlich, einen Delegierten ändern und dem Kunden MyClass einen Delegierten mit anderen als den checkbox Ereignisparametern übergeben.

Hoffe, das hilft.

0

Ich denke, die beste Lösung für das, was Sie brauchen, Rx zu verwenden ist - wenn Sie nicht Angst haben, vorstellen neue Technologie in das Bild (es ist eine ziemlich stabile Version aus bereits und mit go-Live-Lizenz)
dh mit

IObservable<DataType> RangeMissing; 

... die von der Klasse des referenzierten privaten Feldes implementiert (ausgelöst) wird. Dann muss die Elternklasse das nur in eine sehr einfache Eigenschaft (public) einbinden ...

public IObservable<DataType> RangeMissing {get{return _privateField.RangeMissing;} } 

... das ist die ‚grüne‘ Art und Weise Ereignisse der Handhabung und den gesamten Rahmen für solche Zwecke (leicht zu manipulieren Ereignisse erfunden, w/o erfordern alle abonnieren/abbestellen und zwingend notwendig, Codierung - zB auch die Ein einfacher Wrapper wie dein wird zum Problem, ein kleiner, aber unnötiger Code wird benötigt, um geschrieben zu werden.
Sie können Rx durch NuGet in das Projekt installieren (funktioniert für .NET 4, VS 2010)

Das ist, was ich denke, von der Design-Perspektive wird empfohlen,
außer dass Sie nur wollen, könnte wie vorgeschlagen wickeln, oder machen Sie einen ausgefeilteren Wrapper für einen solchen Zweck (aber Rx macht das viel besser) - oder überdenken Sie einige Designentscheidungen, Klassenverantwortlichkeiten - oder ob Sie Ereignisse spezifisch über eine spezifische Implementierung etc. offenlegen (dazu müssten wir viel wissen) mehr Details, jedes Design ist spezifisch).
hoffe das hilft

Verwandte Themen