Laden...

Delegate für "allgemeinen Filter": eigenen Delegatentyp definieren oder Func<...> verwenden?

Erstellt von sth_Weird vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.534 Views
S
sth_Weird Themenstarter:in
469 Beiträge seit 2007
vor 12 Jahren
Delegate für "allgemeinen Filter": eigenen Delegatentyp definieren oder Func<...> verwenden?

hallo,

Ich bastle gerade an einem "allgemeinen Filter" herum. Ich versuchs mal kurz zu erklären...
In der Filter-Konfiguration steht drin, welche Properties eines (eigenen)Typs gefiltert werden können.
Ist das Property ein int, string etc., dann soll der Anwender später einfach eine Zahl, eine Zeichenkette etc eingeben können. Ist das Property aber von einem Referenztyp (eigener Typ, aber alle Typen implementieren dasselbe Interface, ich nenne es mal IData), dann wäre es ja sinnvoll, wenn der Anwender später eine Auswahl aller möglichen Objekte bekommen würde. Falls es zur Verständlichkeit beiträgt: Diese Objekte sollen aus einer Datenbank abgerufen werden.
Meine Filterkonfiguration sollte also schemenhaft so aussehen
"Filterkonfiguration für einen Typ"
(Filter-Property, Funktion)
(Filter-Property, Funktion)
...alle Properties des Type, die gefiltert werden können
wobei die Funktion bei trivialen Typen null ist und bei Referenztypen auf eine Funktion zeigen soll, die aufgerufen werden muss, um eine Liste der möglichen Werte zu bekommen (immer List<IData>).

Das Stichwort delegate ist mir durchaus ein Begriff, ich weiß nur jetzt nicht, in welcher Form ich es benutzen soll...als reines Delegate oder in Form von Func<>? Funktionieren würde denke ich beides, aber welches ist "passender", "schöner", besserer Stil? Ich mein rein "delegate" gab es ja schon seit Anfangszeiten von C#, das Func<> ist erst neuerlich dazugekommen...ist es dann "veraltet" noch das delegate zu verwenden (so wie man schon lange ne List<T> anstelle ner ArrayList verwendet)?
um etwas Code beizusteuern, diese beiden Wege könnte ich mir für den Funktionspointer vorstellen:

delegate List<IMyInterface>LoadFilterSelection(MyType anObject)

oder

Func<MyType, List<IMyInterface>> LoadFilterSelection

Langer Text kurze Frage: Welche Variante ist besser (oder ist es einfach Geschmacksache)?

gruß & danke!
sth_Weird

++++++++++++++++++++~+
Fluchen ist die einzige Sprache, die jeder Programmierer perfekt beherrscht


Linux is for free...if your time is worth nothing
++++++++++++++++++++~+

S
417 Beiträge seit 2008
vor 12 Jahren

Hallo,

also Func<T> ist ja nichts anderes als ein generisches Delegate, welches eben mehrfach überladen existiert, damit man keine eigenen Delegates mehr erstellen muss.
Ich würde Func<T> nehmen.

A
763 Beiträge seit 2007
vor 12 Jahren

Nachdem ich mich halbwegs umgewöhnt habe, finde ich Func etc. recht angenehm.

Was den Filter betrifft, könnte ich mir gut vorstellen, dass das schon mal jemand gemacht hat.

S
sth_Weird Themenstarter:in
469 Beiträge seit 2007
vor 12 Jahren

Vielen Dank für eure Antworten!

Was den Filter betrifft, könnte ich mir gut vorstellen, dass das schon mal jemand gemacht hat.

das hab ich mir auch gedacht, aber leider bisher nichts passendes dafür gefunden (jedenfalls nicht in der Komplexität, die ich brauche), deshalb mach ich's jetzt selber 😃 Falls aber jemand doch noch was findet, kann es gern hier posten, man kann sich da ja Ideen holen.

gruß
sth_Weird

++++++++++++++++++++~+
Fluchen ist die einzige Sprache, die jeder Programmierer perfekt beherrscht


Linux is for free...if your time is worth nothing
++++++++++++++++++++~+

T
381 Beiträge seit 2009
vor 12 Jahren

In deinem Fall spricht nichts gegen Func<T>.

Gründe für ein Eigenes Deletagte könnten die Typsicherheit oder der Zugriffslevel sein. Wenn du z.B. irgendwo ein "Filterdelegate" erwartest kann dir das jeder Liefern der Zugriff auf das Delegate hat. Im Fall von Func<T> also jeder. Hast du ein eigenes delegate was möglichweise sogar internal ist, kannst du sicher sein, dass nur autorisierte Klassen dir das Delegate übergeben.

5.742 Beiträge seit 2007
vor 12 Jahren

Wenn du z.B. irgendwo ein "Filterdelegate" erwartest kann dir das jeder Liefern der Zugriff auf das Delegate hat. Im Fall von Func<T> also jeder. Hast du ein eigenes delegate was möglichweise sogar internal ist, kannst du sicher sein, dass nur autorisierte Klassen dir das Delegate übergeben.

Das stimmt so nicht: Wenn der Member, der den Delegate "erwartet" public ist, muss auch der Delegat öffentlich zugänglich sein.
Und wenn der Member z.B. internal ist, macht die Sichtbarkeit des Delegaten keinerlei Unterschied.

Evtl. wäre aber fast schon ein Interface für einen Filter geeigneter als ein Delegat.

T
381 Beiträge seit 2009
vor 12 Jahren

Das stimmt so nicht: Wenn der Member, der den Delegate "erwartet" public ist, muss auch der Delegat öffentlich zugänglich sein.
Und wenn der Member z.B. internal ist, macht die Sichtbarkeit des Delegaten keinerlei Unterschied.

Hm ja, ich dachte an so etwas wie unten gezeigt. Aber da macht es dann tatsächlich keinen Unterschied ob das Delegate internal ist oder nicht.


    internal delegate void FilterFunc();
    public class ImplementingFilter
    {
        private FilterFunc m_MyFilter;
        internal FilterFunc MyFilter
        {
            get { return m_MyFilter; }
            set { m_MyFilter = value; }
        }


        public ImplementingFilter()
        {
        }

        public void FilterSomething()
        {
            m_MyFilter.Invoke();
        }
    }

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Tarion,

dass nur autorisierte Klassen einen Delegaten übergeben können, liegt dann aber nicht an der Sichtbarkeit des Delegatentyps, sondern an der Sichtbarkeit der Property. Selbst wenn der Delegatentyp public wäre, könnte keine nicht-autorisierte Klassen einen Delegaten übergeben, solange die Property internal ist. Andersherum gilt, was winSharp93 sagte: Wenn die Property öffentlich zugänglich ist, muss es auch der Delegatentyp sein. Insofern nützt das Kriterium der Sichtbarkeit des Delegatentys nicht als Entscheidungshilfe. Damit sollten wir diesen kleinen Ausflug als abgeschlossen betrachten.

herbivore

S
sth_Weird Themenstarter:in
469 Beiträge seit 2007
vor 12 Jahren

Evtl. wäre aber fast schon ein Interface für einen Filter geeigneter als ein Delegat.

hmm wie meinst du das?

Prinzipiell will ich mit der Filter-Konfiguration erreichen, dass ich meine EINE Filteroberfläche für alle möglichen Datentypen verwenden kann. Die Auswahl der filterbaren Eigenschaften ergibt sich ja aus meiner Konfiguration, und wenn in der Konfiguration für eine Eigenschaft eine Funktion hinterlegt ist, dann rufe ich die auf, bekomme eine Liste<IData> und die zeige ich dann zur Auswahl in einer Combobox an.
Wie könnte ich hier die Funktion durch ein Interface ersetzen? Oder meinst du, ich erstelle pro mögliche Funktion eine Instanz so eines Interfaces und rufe für diese eine Funktion auf, die mir die Daten zurückliefert (wäre auch ne Alternative, aber ist die wirklich praktischer oder schieße ich damit eher mit Kanonen auf Spatzen?). Oder wie hast du das gemeint?

gruß & danke
sth_Weird

++++++++++++++++++++~+
Fluchen ist die einzige Sprache, die jeder Programmierer perfekt beherrscht


Linux is for free...if your time is worth nothing
++++++++++++++++++++~+

5.742 Beiträge seit 2007
vor 12 Jahren

Wie könnte ich hier die Funktion durch ein Interface ersetzen? Oder meinst du, ich erstelle pro mögliche Funktion eine Instanz so eines Interfaces und rufe für diese eine Funktion auf, die mir die Daten zurückliefert (wäre auch ne Alternative, aber ist die wirklich praktischer oder schieße ich damit eher mit Kanonen auf Spatzen?)

War nur eine Anregung - so genau, dass man das wirklich beurteilen, ist deine Beschreibung allerdings nicht.

(Filter-Property, Funktion)

Wenn das sowieso schon alles in einer Klasse / einem Interface ist - warum stellst du dann nicht direkt eine Methode bereit?