Anonyme Sammlungen?

7

Ich suche nach Best Practices zum Erstellen von Sammlungen, die aus anonymen Typen erstellt wurden.

Es gibt mehrere Ansätze - das und die meisten Antworten darauf dieser Thread setzt die gesamte anonyme Sammlung voraus kann in einer Aussage konstruiert werden.

Da anonyme Typen normalerweise verwendet werden, um Klassen zu ersetzen, die zum temporären Speichern verwendet werden sollen (wie in diese SO-Antwort ), ich möchte vermeiden, eine Klasse für anonyme Sammlungen zu erstellen und zu verwenden, wie diesen Beitrag schlägt vor.

In meinem Fall wiederhole ich eine Sammlung - für jedes Objekt in der Sammlung möchte ich verwandte Objekte in einem anonymen Typ (als Tupel) sammeln. Ich brauche diese anonymen Typen, um sie in eine Sammlung zu packen und sie dann für weitere Arbeiten zu sortieren.

Andere Ansätze, die ich in Betracht gezogen habe:

  1. Verwenden Sie ein Objekt [] oder ArrayList (den Vorteil des anonymen Typs zu verlieren)
  2. Erstellen einer Wrapper-Klasse für die erforderlichen Elemente (die Notwendigkeit für den anonymen Typ entfällt)

Dies ist der einzige Ort in meinem Code, wo ich eine solche Sammlung brauche - was wäre der beste Ansatz?

Zusätzliche Informationen:

Ich arbeite mit älteren .NET 1.1-Objekten, daher sind die Sammlungen, mit denen ich arbeite, stark typisierte Auflistungen, die IEnumerable implementieren, und daher funktionieren die meisten Linq-Erweiterungsmethoden wie .Select nicht:

Codebeispiel

%Vor%

Auflösung

Am Ende habe ich ein allgemeines Wörterbuch verwendet, um die zusammengehörigen Elemente zu sammeln und mit .OrderBy () zu sortieren - hässlich, aber es funktioniert ... und ist besser als der vorhandene Code.

    
Oded 19.03.2009, 10:20
quelle

6 Antworten

6

Für eine ganz andere Antwort ... LINQ?

  

In meinem Fall wiederhole ich über eine   Sammlung - für jeden Artikel in der   Sammlung möchte ich sammeln   verwandte Objekte in einem anonymen Typ   (als Tupel handeln). Ich brauche diese   anonyme Typen, die in eine   Sammlung und dann sortieren sie nach   weitere Arbeit.

Das klingt wie:

%Vor%     
Marc Gravell 19.03.2009, 10:35
quelle
20

Wenn Sie mit einem Array zufrieden sind, können Sie einen Array-Initialisierer verwenden:

%Vor%

Sie können dann ToList() aufrufen, wenn Sie List<T> out erhalten möchten. Marc's Lösung wird etwas effizienter sein als ToList() aufzurufen, da das zusätzliche Kopieren nicht nötig ist, aber ich denke Ich würde wahrscheinlich die "array und dann ToList ()" Lösung in den meisten Fällen verwenden weniger Unordnung. Natürlich, wenn die Leistung für diesen Code entscheidend ist, ändert sich die Situation.

BEARBEITEN: Wenn Sie über eine Sammlung iterieren, verwenden Sie einfach Select :

%Vor%     
Jon Skeet 19.03.2009 10:29
quelle
4

Eine Option besteht darin, ein Beispielelement zu verwenden, um die Sammlung über eine generische Typinferenz zu erstellen, zum Beispiel:

%Vor%

Sie können dies auch tun ohne erstellen eine Instanz (aber mit einer anonymen Methode, die nie ruft Anrufer), aber ich glaube nicht, es spart wirklich etwas ... wir erstellen möglicherweise keine Instanz des Objekts, aber wir erstellen eine Instanz eines Delegaten, also nicht viel von einem Speichern ...

Sie erwähnen auch das Sortieren der Daten; Sehen Sie sich die Antwort hier an, um einen Weg zu finden Verwenden Sie List<T>.Sort mit einem Lambda und damit mit anonymen Typen - dh

%Vor%     
Marc Gravell 19.03.2009 10:22
quelle
1

LINQ ist der richtige Weg. Angenommen, Sie möchten die verwandten Objekte A, B und C jedes Elements in einem Sammlungselement abrufen und nach dem verwandten Objekt A sortieren, gehen Sie wie folgt vor.

%Vor%

Sie erhalten eine Sammlung von Objekten eines anonymen Typs mit den drei Eigenschaften A, B und C, die auf die verwandten Objekte eingestellt sind, die vom zugehörigen Objekt A angeordnet sind.

Ich habe das nicht überprüft, aber Sie sollten die relatedObject-Auflistung später erweitern können. Führen Sie einfach Folgendes aus, um ein einzelnes neues Element hinzuzufügen. Dies sollte funktionieren, da es nur einen anonymen Typ pro Assembly gibt, wenn die Namen und Typen jeder Eigenschaft übereinstimmen.

%Vor%

Ziemlich hässlich wegen der Enumerable.Repeat (), aber es wird ganz nett, wenn Sie mit einer Sammlung neuer Elemente statt mit einem einzelnen neuen Element verbinden.

    
Daniel Brückner 19.03.2009 10:47
quelle
0
  

diesen und die meisten Antworten darauf   Thread nehme an, dass das ganze anonym ist   Sammlung kann in einem konstruiert werden   Aussage.

Ja, normalerweise erstellen Sie eine Sammlung anonymer Typen in einer einzelnen Anweisung. Wenn Sie mehr Anweisungen benötigen, können Sie mit einer ziemlich nutzlosen Sammlung von verschiedenen anonymen Typen enden.

Anonyme Typen sind nützlich, wenn Sie sie in einer einzigen Anweisung erstellen und sofort verwenden. Wenn die Erstellung der Sammlung oder die weitere Verarbeitung ein wenig komplexer ist, verliert der anonyme Typ etwas von seiner Nützlichkeit. Beispielsweise können Sie einen anonymen Typ nicht effizient an eine Methode zur Verarbeitung übergeben, da die Methode den Typ des Objekts nicht kennt und daher Reflektion verwenden muss, um etwas daraus zu ziehen.

Wenn Sie wiederholt nach Elementen in dieser Sammlung anonymer Typen suchen, möchten Sie möglicherweise einen benannten Typ erstellen, damit Sie sie in ein Dictionary für eine viel schnellere Suche einfügen können.

    
Guffa 19.03.2009 10:47
quelle
0

Ich bin auf diese Frage gestoßen, als ich nach einer Möglichkeit suchte, eine temporäre Liste temporärer Objekte zu erstellen. Warum sollte ich so etwas schaffen? Ich suchte nach einer schnellen Möglichkeit, JSON für eine Liste von Objekten zurückzugeben, die aus einigen Werten eines anderen Objekts erstellt wurden. Hier ist was ich meine.

Angenommen, ich habe eine Employee-Klasse auf der Serverseite, die in C # folgendermaßen aussieht:

%Vor%

Außerdem habe ich eine Sammlung von Objekten, die ich leicht durchspielen kann, etwa so:

%Vor%

Nun möchte ich auf meine aufrufende Webseite die gesamte Sammlung von Mitarbeitern zurückgeben, aber ich möchte nur den ersten, letzten Namen für jeden . Ich möchte, dass sie als JSON zurückgegeben werden.

Hier ist der wichtige Punkt

Ich möchte nicht jede Eigenschaft im Employee-Objekt zurückgeben.

Ich weiß, dass ich auf einfache Weise einen anonymen Typ erstellen kann, indem ich die allEmployee-Sammlung durchlaufe und jedes Mal ein neues Objekt erstelle.

Es würde ungefähr so ​​aussehen:

%Vor%

Was ist der Typ eines anonymen Typs? :)

Der Trick besteht jetzt darin, dass ich eine ganze Sammlung (Liste & lt; & gt;) dieser anonymen Objekte haben möchte. Ich habe jedoch keine Möglichkeit, der Liste einen Typ zur Verfügung zu stellen, den ich verwenden werde. Ich kann keine erstellen   List<unknown> allTempObjects = new List<unknown>();

Oder kann ich?

Mit dynamic ist es möglich

Ich kann Folgendes tun und es funktioniert großartig:

%Vor%

Sie werden auf der Client-Seite JSON sehen, das wie folgt aussieht:

%Vor%

Schließlich können Sie sich fragen, warum ich das machen möchte. Die einfache Antwort ist, dass ich einen neuen Typ haben möchte, der nur zum Serialisieren verwendet wird, um an meinen Kunden zu senden. Ein guter Grund für einen anonymen Typ und eine anonyme Sammlung anonymer Typen, meinst du nicht?

    
raddevus 16.06.2014 14:57
quelle