Laden...

Anzahl registrierter Eventhandler ermitteln

Letzter Beitrag vor 13 Jahren 18 Posts 1.475 Views
Anzahl registrierter Eventhandler ermitteln

Moin !

Bekommt man eigentlich raus wieviele Actions einer Klasse zugeordnet sind? Und kommt man über die Actions ggf. sogar auf das Objekt?

    class Inp : General, IInput
    {
        public void Run(string text)
        {
            this.OnX(text);
        }

        public event Action<string> OnX;
    }

Dies ist ein ganz simpeles Input Objekt (EBC). Diesem kann ich nun z.B. Ausgänge anhängen / binden:

_Inp.OnX += _Out1.ProcessOut;

Kann ich irgendwie raus bekommen

  1. Ob überhaupt und wenn wieviele Actions dort angehängt sind?
  2. Über die Action Einträge auf die Objekte kommen? (Also im obigen Beispiel anhand von dem Eintrag in OnX auf das Objekt _Out1 schließen).

Greetz Dominik

  1. Ob überhaupt und wenn wieviele Actions dort angehängt sind?

OnX!=null

  1. Über die Action Einträge auf die Objekte kommen? (Also im obigen Beispiel anhand von dem Eintrag in OnX auf das Objekt _Out1 schließen).

Das thema wurde schonmal besprochen und in den meißten fällen ist es schlichtweg unsinnig dies zu tun. Wenn du unbedingt willst: GetInvocationList() und Target

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

Moin !

OnX!=null

Damit kriege ich ja nur raus ob es leer ist.
Kriegt man auch die Anzahl raus?

unsinnig dies zu tun

Das habe ich schon befürchtet. Das werde ich dann mal anders lösen.

Greetz Dominik

Kriegt man auch die Anzahl raus?

Wie man sich leicht denken könnte, wenn man die methode einmal angeguckt hätte, geht dies ebenfalls mit GetInvocationList().

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

Moin !

geht dies ebenfalls mit GetInvocationList().

Ah, nu hab ichs auch kapiert. Danke 👍

Greetz Dominik

Hallo moelski,

es ist ein Hinweis auf schlechtes oder falsches Design, wenn dich die Anzahl interessiert. Es hat ein Objekt schlicht nichts anzugehen, wer seine Events abonniert hat. Events sind dazu da, um Abhängigkeiten zu vermeiden. Da ist es vollkommen kontraproduktiv, diesen Abhängigkeiten dann doch wieder nachzugehen.

herbivore

Guten Morgen herbivore,

ich könnte mir vorstellen das es zu debugging Zwecken ganz nützlich sein kann. Ich muss zugeben das auch noch nie gebraucht zu haben, dennoch könnte ich mir vorstellen das bei der Suche nach ganz "komischen" Fehlern die Information ganz nützlich sein kann.

Grüße
Nils

Moin !

zu debugging Zwecken ganz nützlich sein kann

Dafür war / ist es auch gedacht.

Im Grunde habe ich ich noch folgendes Problem - denke das passt hier noch einigermassen zum Thema...

Ich progge ja gerade an einem EBC System. Und nehmen wir mal den ganz einfachen Fall : Input -> Output. Also nur 2 Objekte.

Im Code schaut das so:

    class Inp : General, IInput
    {
        public void Run(string text)
        {
            this.OnX(text);
        }
        public event Action<string> OnX;
    }

    class Out : General, IOutput
    {
        public void ProcessOut(string x)
        {
            Console.WriteLine(x);
        }
    }

Davon erstellt man sich zwei Instanzen und erstellt ein Binding:

Inp  _Inp   = new Inp();
Out _Out1  = new Out();
_Inp.OnX += _Out1.ProcessOut;

Das Konstrukt kann man nun am Input mir Run("...") anschubsen und es kommt was bei Output raus. Alles im Lot.

Nun möchte ich aber u.A. eine WinForms Anwendung oben drüber haben mit der ich
a) die Objekte binden kann
b) möchte ich dort natürlich anzeigen welches Element schon mit welchen verbunden ist.

Punkt a habe ich hinbekommen - noch nicht schön, aber es klappt 😉

Aber bei b ist mir noch nichts gutes eingefallen. Meine erste Idee war dann eben über die registrierten Events rauszukriegen, welche Objekte als nächstes in der Kette kommen. Fürs Debugging sicher ok, aber praktisch Unsinn.

Nur wie sonst tun? Meine derzeitige Idee wäre jedem Objekt noch eine Liste anzufügen wo sich die Folgeelemente eintragen. Dann könnte man sich rel. einfach durch die Listen vom Eingang bis zum Ausgang hangeln.

Bedeutet aber glaube ich auch einen ganz schönen Aufwand an Code!?

Hat jemand eine Idee wie man das elegant lösen könnte?

Greetz Dominik

Hallo moelski,

da man EventHandler von außen zwar setzen (und entfernen kann), aber - außer per Reflection - von außen (absichtlich) nicht abfragen kann, ist das keine geeignete Repräsentation der Daten. Du wirst nicht umhinkommen, dass sich das GUI die Verdrahtung der Objekte in einer eigenen Datenstruktur merkt. Da sich das GUI jedoch sowieso noch zusätzliche Informationen zu dem Objekten und den Verdrahtungen merken muss (Position der Objekte, genauer Verlauf der Drähte, welches Objekt gerade selektiert ist usw.), sollte das aber kein großes Problem sein.

Mit einer einfachen Liste wirst du wohl nicht hinkommen, außer du beschränkst die Verdrahtung auf einfache, sequentielle Ketten von Objekten. Aber es spricht nichts dagegen, pro Objekt ein eigenes Objekt im Zusatzinformationen im GUI zu schaffen, das sich auch merkt, mit welchen anderen Objekten das Objekt verbunden ist.

herbivore

Moin !

Was ich derzeit schon habe ist eine generische List. Dort trage ich alle erzeugten Objekte ein.

Wenn ich nun jedem Objekt eine Liste hinzufüge und dort die Folgeobjekte eintrage, würde das dann nicht schon klappen? 🤔

Dann habe ich auf der einen Seite eine Liste mit Objektreferenzen und die Events sind eine ganz andere Schiene ...

Greetz Dominik

ich könnte mir vorstellen das es zu debugging Zwecken ganz nützlich sein kann.

Aber nur für das Immediate Fenster oder für den Quickwatch.
Zusätzlich könnte ich mir noch vorstellen das bei einer besonderen Exception sowas mitgeloggt wird.... Oder wenn man so einen custom "Dump" erzeugt...

Ansonsten sollte man sowas nicht verwenden.

Hallo moelski,

Wenn ich nun jedem Objekt eine Liste hinzufüge und dort die Folgeobjekte eintrage, würde das dann nicht schon klappen?

das reicht dem GUI auf jeden Fall, um festzustellen, welches Objekt mit welchen (folgenden) Objekten verdrahtet ist. Wenn die Verdrahtung immer automatisch gezeichnet (geroutet) wird, dann ist das ausreichend. Wenn du dir zu der Verdrahtung weitere Informationen merken willst, also z.B. an welchen Positionen die Verdrahtung abknicken bzw. welche Punkt sie durchlaufen soll, dann bräuchte man noch weitere Objekte, um diese Eigenschaften zu repräsentieren und dann wäre es besser, wenn sich jedes Objekt seine Verbindungsobjekte merken würde, statt direkt die Objekte, mit denen es verbunden ist. Das finde ich aber alles relativ offensichtlich. Ich denke, das bekommst du jetzt auch alleine hin.

herbivore

Moin !

also z.B. an welchen Positionen die Verdrahtung abknicken bzw. welche Punkt sie durchlaufen soll, dann bräuchte man noch weitere Objekte, um diese Eigenschaften zu repräsentieren und dann wäre es besser, wenn sich jedes Objekt seine Verbindungsobjekte merken würde, statt direkt die Objekte, mit denen es verbunden ist

Der Part ist mir noch nicht so ganz klar. Aber bis ich da ankomme dauert es auch noch etwas 🙂

Ich komme jetzt erstmal weiter. Danke !

Greetz Dominik

Hallo moelski,

wenn das Programm den Verlauf aller Verbindungen nur aus dem jeweiligen Start- und dem Endpunkt automatisch berechnet, sieht das manchmal nicht so schön aus. Deshalb erlauben es manche Programme dem Benutzer, den genauen Verlauf der Verbindungen mit der Maus selbst festzulegen. Wenn dein Programm das können sollen, musst du dir natürlich diese Informationen auch irgendwo merken. Dazu würde man dann vermutlich eine weitere Klasse schreiben, die diese Daten enthält. Die eigentlichen Objekte würde sich dann nicht merken, mit welchen anderen Objekten sie verbunden sind, sondern sie würden sich eine Liste mit Verbindungsobjekten merken.

herbivore

Ah ok.

Ich werde es aber erstmal einfach versuchen - also ohne Verbindungsobjekt.

Vielleicht noch eine abschließende Frage (auch wenn ich es jetzt noch nicht umsetze). Wie würde so ein Verdindungsobjekt ganz grundlegend aussehen?

So:

    class Connection
    {
        Inp Input;
        Out Output;
    }

?

Greetz Dominik

Hallo moelski,

wenn du dir wie jetzt nur merkst, welche Objekte an den Ausgängen hängen, dann brauchst du dir auch in dem Verbindungsobjekt nur das Objekt am Ausgang merken. Aber wie schon gesagt, ich finde das alles relativ offensichtlich. Das sind ja alles die üblichen und bekannten Vorgehensweise zur Repräsentation eines Graphen.

herbivore

Ich würde Sie wahrscheinlich so aufbauen:


class Connection
    {
public Guid Id {get;set;}
public string Name {get;set;}        
public Inp Input {get;set}
public Out Output{get;set;}
public List<Point>{get;set;}
    }