476 Stimmen

Eine generische Liste anonymer Klassen

In C# 3.0 können Sie anonyme Klassen mit der folgenden Syntax erstellen

var o = new { Id = 1, Name = "Foo" };

Gibt es eine Möglichkeit, diese anonymen Klassen zu einer generischen Liste hinzuzufügen?

Exemple :

var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };

List<var> list = new List<var>();
list.Add(o);
list.Add(o1);

Ein weiteres Beispiel:

List<var> list = new List<var>();

while (....)
{
    ....
    list.Add(new {Id = x, Name = y});
    ....
}

5voto

Jermismo Punkte 232

Sie können es so machen:

var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };

var array = new[] { o, o1 };
var list = array.ToList();

list.Add(new { Id = 3, Name = "Yeah" });

Es scheint mir ein wenig "hacky", aber es funktioniert - wenn Sie wirklich brauchen, um eine Liste zu haben und kann nicht nur die anonyme Array verwenden.

5voto

Peter Davidson Punkte 394

Dies ist eine alte Frage, aber ich dachte, ich würde in meinem C# 6 Antwort setzen. Ich muss oft Testdaten einrichten, die leicht als Liste von Tupeln in den Code eingegeben werden können. Mit ein paar Erweiterungsfunktionen ist es möglich, dieses schöne, kompakte Format zu haben, ohne die Namen bei jedem Eintrag zu wiederholen.

var people= new List<Tuple<int, int, string>>() {
    {1, 11, "Adam"},
    {2, 22, "Bill"},
    {3, 33, "Carol"}
}.Select(t => new { Id = t.Item1, Age = t.Item2, Name = t.Item3 });

Dies gibt eine IEnumerable - wenn Sie eine Liste, die Sie hinzufügen können, dann fügen Sie einfach ToList() wollen.

Die Magie kommt von der benutzerdefinierten Erweiterung Add-Methoden für Tupel, wie beschrieben unter https://stackoverflow.com/a/27455822/4536527 .

public static class TupleListExtensions    {
    public static void Add<T1, T2>(this IList<Tuple<T1, T2>> list,
            T1 item1, T2 item2)       {
        list.Add(Tuple.Create(item1, item2));
    }

    public static void Add<T1, T2, T3>(this IList<Tuple<T1, T2, T3>> list,
            T1 item1, T2 item2, T3 item3) {
        list.Add(Tuple.Create(item1, item2, item3));
    }

// and so on...

}

Das Einzige, was mir nicht gefällt, ist, dass die Typen von den Namen getrennt sind, aber wenn Sie wirklich keine neue Klasse erstellen wollen, können Sie mit diesem Ansatz trotzdem lesbare Daten erhalten.

4voto

morlock Punkte 51
var list = new[]{
new{
FirstField = default(string),
SecondField = default(int),
ThirdField = default(double)
}
}.ToList();
list.RemoveAt(0);

4voto

nawfal Punkte 65966

Für Ihr zweites Beispiel, bei dem Sie eine neue Datei initialisieren müssen List<T> Eine Idee ist, eine anonyme Liste zu erstellen und diese dann zu löschen.

var list = new[] { o, o1 }.ToList();
list.Clear();

//and you can keep adding.
while (....)
{
    ....
    list.Add(new { Id = x, Name = y });
    ....
}

Oder als Erweiterungsmethode, sollte einfacher sein:

public static List<T> GetEmptyListOfThisType<T>(this T item)
{
    return new List<T>();
}

//so you can call:
var list = new { Id = 0, Name = "" }.GetEmptyListOfThisType();

Oder wahrscheinlich sogar kürzer,

var list = new int[0].Select(x => new { Id = 0, Name = "" }).Tolist();

1voto

BrainStorm.exe Punkte 1457

Abgeleitet von diese Antwort Ich habe zwei Methoden gefunden, die diese Aufgabe erfüllen können:

    /// <summary>
    /// Create a list of the given anonymous class. <paramref name="definition"/> isn't called, it is only used
    /// for the needed type inference. This overload is for when you don't have an instance of the anon class
    /// and don't want to make one to make the list.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="definition"></param>
    /// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
    public static List<T> CreateListOfAnonType<T>(Func<T> definition)
#pragma warning restore RECS0154 // Parameter is never used
    {
        return new List<T>();
    }
    /// <summary>
    /// Create a list of the given anonymous class. <paramref name="definition"/> isn't added to the list, it is
    /// only used for the needed type inference. This overload is for when you do have an instance of the anon
    /// class and don't want the compiler to waste time making a temp class to define the type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="definition"></param>
    /// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
    public static List<T> CreateListOfAnonType<T>(T definition)
#pragma warning restore RECS0154 // Parameter is never used
    {
        return new List<T>();
    }

Sie können die folgenden Methoden verwenden

var emptyList = CreateListOfAnonType(()=>new { Id = default(int), Name = default(string) });
//or
var existingAnonInstance = new { Id = 59, Name = "Joe" };
var otherEmptyList = CreateListOfAnonType(existingAnonInstance);

Diese Antwort hat eine ähnliche Idee, aber ich habe sie erst gesehen, nachdem ich diese Methoden entwickelt hatte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X