Verwenden der Auflistungsinitialisierungssyntax für benutzerdefinierte Typen?

9

Ich habe eine große statische Liste, die im Grunde eine Nachschlagetabelle ist, also initialisiere ich die Tabelle in Code.

%Vor%

Das reale LookupItem hat viele weitere Eigenschaften, daher habe ich einen Konstruktor hinzugefügt, um ein kompakteres Initialisierungsformat zu ermöglichen:

%Vor%

Was ich wirklich tun möchte, ist, das Initialisiererformat der Sammlung für das Objekt selbst zu verwenden, damit ich new LookupItem() in jeder Zeile loswerden kann. zB:

%Vor%

Ist das möglich? Ich denke, es ist so, weil die KeyValuePair 's von Dictionary<> auf diese Weise initialisiert werden können.

MSDN Status:

  Mit

Auflistungsinitialisierer können Sie ein oder mehrere Elemente angeben   Initialisierungen, wenn Sie eine Sammlungsklasse initialisieren, die implementiert   IEnumerable . Die Elementinitialisierer können ein einfacher Wert sein, ein   Ausdruck oder ein Objektinitialisierer. Mithilfe eines Auflistungsinitialisierers   Sie müssen nicht mehrere Aufrufe an die Add-Methode der angeben   Klasse in Ihrem Quellcode; Der Compiler fügt die Aufrufe hinzu.

Bedeutet das, dass ich IEnumerable für meine LookupItem -Klasse implementieren muss und jeden Parameter zurückgeben muss? Meine Klasse ist jedoch keine Sammelklasse.

    
GazTheDestroyer 08.02.2012, 13:36
quelle

4 Antworten

12

Ich denke, Sie müssen eine benutzerdefinierte Sammlung anstelle von Liste erstellen. Nennen Sie es zum Beispiel LookupItemTable. Geben Sie dieser Auflistung eine Add-Methode (int, int, float, float), und implementieren Sie IEnumerable. Zum Beispiel:

%Vor%

Ich habe jetzt den obigen Code ausprobiert und es scheint für mich zu funktionieren.

    
Weeble 08.02.2012, 13:42
quelle
6

Schnellkorrektur : Erstelle deinen eigenen List Typ mit einer Add Überladung, die mehrere Argumente benötigt:

%Vor%

Funktioniert nun genau so, wie Sie möchten:

%Vor%

Grundlegende Antwort:

Sie vermischen Objektinitialisierer und Auflistungsinitialisierer . Einfach gesagt:

Objektinitialisierer sind ein syntaktischer Trick, der im Hintergrund die Eigenschaftensatzmethoden für jede benannte Eigenschaft mit dem angegebenen Wert aufruft.

Sammlungsinitialisierer sind ein syntaktischer Trick, der im Hintergrund:

  • Für einen Array type: Füllen Sie das Array mit den Elementen
  • Für jeden anderen Typ, der IEnumerable implementieren muss: Rufen Sie die Methode Add für jede untergeordnete Klammer auf.

Das ist alles da ist es. Betrachten Sie zum Beispiel den folgenden Hack:

%Vor%

Sie sollten das nie in einem echten Programm tun, aber ich hoffe, dieses Beispiel und die Ergebnisse zu untersuchen, besonders wenn Sie Schritt für Schritt debuggen, wird Ihnen helfen, die Initialisierer klar zu verstehen und eine gute Lösung für Ihr aktuelles Szenario auszuwählen. p>     

Joshua Honig 08.02.2012 14:23
quelle
4

Sie versuchen, einen Auflistungsinitialisierer in der Liste selbst zu verwenden, nicht auf Ihrem Typ:

%Vor%

Also wird nach einer Add -Methode mit vier Parametern auf List<T> gesucht, und diese existiert nicht.

Sie müssen Ihre eigene Auflistung -Klasse implementieren, um einen benutzerdefinierten Auflistungsinitialisierer zu verwenden. Während Sie List<T> verwenden, bleiben Sie bei den Konstruktoraufrufen hängen, die Sie haben.

    
Jon Skeet 08.02.2012 13:42
quelle
0
  

Bedeutet das, dass ich IEnumerable für meine LookupItem-Klasse implementieren muss   und jeden Parameter zurückgeben? Meine Klasse ist jedoch keine Sammelklasse.

Nein, es bedeutet, dass List<LookupItem> implementiert IEnumerable , weshalb Sie

schreiben können %Vor%

Es bedeutet auch, dass, wenn Ihre LookupItem eine Sammlung war, die IEnumerable implementiert hat, Sie Folgendes hätten schreiben können:

%Vor%     
ken2k 08.02.2012 13:46
quelle