Ist das automatische Hinzufügen von Indexern zu Wörterbüchern und Sammlungen eine gute Designentscheidung?

7

Wann ist es für einen Indexer akzeptabel, Elemente automatisch zu einer Sammlung / einem Wörterbuch hinzuzufügen? Ist dies sinnvoll oder im Gegensatz zu bewährten Verfahren?

%Vor%

Beispiel, wie dies in einer Sammlung verwendet werden kann:

%Vor%     
chilltemp 27.08.2010, 19:42
quelle

6 Antworten

12

Es gibt zwei Probleme, die Sie beachten sollten - beides deutet darauf hin, dass dies eine schlechte Idee ist.

Erstens ist das Erben von .NET BCL-Auflistungstypen in der Regel keine gute Idee. Der Hauptgrund dafür ist, dass die meisten Methoden für diese Typen (wie Add und Remove ) nicht virtuell sind - und wenn Sie Ihre eigenen Implementierungen in einer abgeleiteten Klasse bereitstellen, werden sie nicht aufgerufen, wenn Sie Ihre Sammlung weitergeben der Basistyp. In Ihrem Fall, indem Sie die Eigenschaft Dictionary<TK,TV> indexer ausblenden, erstellen Sie eine Situation, in der ein Aufruf mit einer Basisklassenreferenz etwas anderes tut als ein Aufruf mit einer abgeleiteten Klassenreferenz ... eine Verletzung der Liskow-Substitutionsprinzip :

%Vor%

Zweitens und noch wichtiger ist das Erstellen eines Indexers, der ein Element einfügt, wenn Sie versuchen, ein zu finden, völlig unerwartet . Indexer haben die Operationen get und set eindeutig definiert. Die Implementierung der Operation get zum Ändern der Sammlung ist sehr schlecht.

Für den Fall, den Sie beschreiben, ist es viel besser, eine Erweiterungsmethode zu erstellen, die für jedes Wörterbuch geeignet ist. Solch eine Operation ist weniger überraschend in dem, was sie tut, und erfordert auch nicht das Erstellen eines abgeleiteten Sammlungs-Typs:

%Vor%     
LBushkin 27.08.2010, 20:13
quelle
3

Ohne weitere Informationen darüber, was Sie tun, sieht das für mich wie ein überraschendes Verhalten aus. Ich hoffe, dass Sie aus dem Kontext (d. H. Nennen Sie es AutoInitializingDictionary oder etwas) sehr klar machen, was zu erwarten ist.

Ich würde es persönlich bevorzugen, dies eher zu einer Methode als zu einem Indexer zu machen; etwas wie D.FindOrCreate . (Ich habe das Gefühl, dass es einen idiomatischen Namen für eine Methode gibt, die das tut, was ich vorübergehend vergessen habe.)

    
mquander 27.08.2010 19:45
quelle
3

Ich würde sagen, das verstößt gegen zwei Prinzipien. 1) Prinzip der geringsten Überraschung. Und 2) dass Getter nichts ändern sollten.

Ich würde nicht erwarten, ein Paar {"foo", null} hinzuzufügen, wenn foo nicht in der Sammlung existiert.

%Vor%     
Conrad Frix 27.08.2010 20:08
quelle
2

Ich denke, es ist vollkommen in Ordnung, solange dieses Verhalten vollkommen klar ist. Ich habe 2 Decorator Klassen:

%Vor%

und

%Vor%

Die zweite Klasse ist perfekt für Counter und Muster wie IDictionary<K,List<V>> ; Ich kann

tun %Vor%

anstelle der mühsamen:

%Vor%     
Ani 27.08.2010 19:59
quelle
2

Der Hauptgrund, warum ich besorgt wäre, ist, dass es nicht threadsicher wäre. Mehrere Leser, die alle gleichzeitig versuchen, in das Dictionary zu schreiben, würden eine sorgfältige Sperrverwaltung benötigen, die Sie wahrscheinlich zuerst nicht für richtig halten (oder richtig machen).

    
Gabe 30.08.2010 14:04
quelle
0
  

Wann ist es für einen Indexer akzeptabel?   um automatisch Elemente zu einem hinzuzufügen   Sammlung / Wörterbuch?

Nie

  

Ist das vernünftig oder gegensätzlich?   Best Practices?

Im Gegensatz zu bewährten Verfahren

Wenn die Klasse entsprechend benannt wird, wäre das akzeptabel. Ich würde stattdessen persönlich GetOrAdd verwenden.

    
TheSoftwareJedi 30.08.2010 13:50
quelle