Frage

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

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

Gibt es eine Möglichkeit, diese anonyme Klasse auf eine generische Liste hinzufügen?

Beispiel:

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});
    ....
}
War es hilfreich?

Lösung

Sie können tun:

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

Es gibt viele Möglichkeiten, diese Katze häuten, aber im Grunde werden sie alle nutzen Typinferenz irgendwo - das heißt, Sie haben eine generische Methode (möglicherweise als Erweiterung Methode) zu rufen. Ein weiteres Beispiel könnte sein:

public static List<T> CreateList<T>(params T[] elements)
{
     return new List<T>(elements);
}

var list = CreateList(o, o1);

Sie erhalten die Idee:)

Andere Tipps

Hier ist die Antwort.

string result = String.Empty;

var list = new[]
{ 
    new { Number = 10, Name = "Smith" },
    new { Number = 10, Name = "John" } 
}.ToList();

foreach (var item in list)
{
    result += String.Format("Name={0}, Number={1}\n", item.Name, item.Number);
}

MessageBox.Show(result);

Es gibt viele Möglichkeiten, dies zu tun, aber einige der Antworten hier eine Liste erstellen, die Müll-Elemente enthält, die Sie die Liste löschen erfordert.

Wenn Sie sich für eine leere Liste der gattungsgemäßen Art suchen, verwenden Sie eine Select gegen eine Liste von Tupeln auf die leere Liste. Es werden keine Elemente instanziiert.

Hier ist der Einzeiler eine leere Liste zu erstellen:

 var emptyList = new List<Tuple<int, string>>()
          .Select(t => new { Id = t.Item1, Name = t.Item2 }).ToList();

Dann können Sie es mit Ihrem generischen Typ hinzufügen:

 emptyList.Add(new { Id = 1, Name = "foo" });
 emptyList.Add(new { Id = 2, Name = "bar" });

Als Alternative können Sie wie unten etwas tun, um die leere Liste zu erstellen (Aber ich ziehe das erste Beispiel, weil Sie es für eine besiedelte Sammlung von Tupeln auch verwenden können):

 var emptyList = new List<object>()
          .Select(t => new { Id = default(int), Name = default(string) }).ToList();   

Nicht genau, aber man kann List<object> sagen und die Dinge funktionieren. Allerdings list[0].Id wird nicht funktionieren.

Dies funktioniert zur Laufzeit in C # 4.0 durch einen List<dynamic>, das heißt nicht IntelliSense bekommen.

Ich denke

List<T> CreateEmptyGenericList<T>(T example) {
    return new List<T>();
}

void something() {
    var o = new { Id = 1, Name = "foo" };
    var emptyListOfAnonymousType = CreateEmptyGenericList(o);
}

funktioniert.

Sie auch interessieren könnten es wie folgt zu schreiben:

void something() {
    var String = string.Emtpy;
    var Integer = int.MinValue;
    var emptyListOfAnonymousType = CreateEmptyGenericList(new { Id = Integer, Name = String });
}

Normalerweise verwende ich die folgenden; vor allem, weil man dann mit einer Liste „Start“, die leer ist.

var list = Enumerable.Range(0, 0).Select(e => new { ID = 1, Name = ""}).ToList();
list.Add(new {ID = 753159, Name = "Lamont Cranston"} );
//etc.

In letzter Zeit, ich habe es wie folgt statt zu schreiben:

var list = Enumerable.Repeat(new { ID = 1, Name = "" }, 0).ToList();
list.Add(new {ID = 753159, Name = "Lamont Cranston"} );

die Wiederholungsmethode verwenden würden Sie auch erlauben, zu tun:

var myObj = new { ID = 1, Name = "John" };
var list = Enumerable.Repeat(myObj, 1).ToList();
list.Add(new { ID = 2, Name = "Liana" });

.., die Ihnen die erste Liste mit dem ersten Eintrag gibt bereits hinzugefügt.

Sie können dies tun, in Ihrem Code.

var list = new[] { new { Id = 1, Name = "Foo" } }.ToList();
list.Add(new { Id = 2, Name = "Bar" });

überprüfte ich die IL auf mehrere Antworten. Dieser Code effizient liefert eine leere Liste:

    using System.Linq;
    …
    var list = new[]{new{Id = default(int), Name = default(string)}}.Skip(1).ToList();

neueste Version 4.0 kann wie dynamische Verwendung unter

var list = new List<dynamic>();
        list.Add(new {
            Name = "Damith"
    });
        foreach(var item in list){
            Console.WriteLine(item.Name);
        }
    }

Hier ist mein Versuch.

List<object> list = new List<object> { new { Id = 10, Name = "Testing1" }, new {Id =2, Name ="Testing2" }}; 

Ich kam auf diese, wenn ich etwas ähnliches für die Herstellung einer Anonymous-Liste für einen benutzerdefinierten Typ geschrieben hat.

Hier ist eine andere Methode, eine Liste von anonymen Typen erstellen, die Sie mit einer leeren Liste starten kann, aber immer noch Zugriff auf IntelliSense hat.

var items = "".Select( t => new {Id = 1, Name = "foo"} ).ToList();

Wenn Sie das erste Element halten wollte, legte nur einen Buchstaben in der Zeichenkette.

var items = "1".Select( t => new {Id = 1, Name = "foo"} ).ToList();

Statt dessen:

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);

Sie können dies tun:

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

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

Allerdings werden Sie einen compiletime Fehler, wenn Sie versuchen, so etwas wie dies in einem anderen Rahmen zu tun, obwohl es zur Laufzeit funktioniert:

private List<object> GetList()
{ 
    List<object> list = new List<object>();
    var o = new { Id = 1, Name = "Foo" }; 
    var o1 = new { Id = 2, Name = "Bar" }; 
    list.Add(o); 
    list.Add(o1);
    return list;
}

private void WriteList()
{
    foreach (var item in GetList()) 
    { 
        Console.WriteLine("Name={0}{1}", item.Name, Environment.NewLine); 
    }
}

Das Problem ist, dass nur die Mitglieder des Objekts zur Laufzeit zur Verfügung stehen, obwohl intellisense die Eigenschaften zeigen id und Namen .

In .net 4.0 eine Lösung ist das Schlüsselwort zu verwenden, dynamischen istead von Objekt im Code oben.

Eine andere Lösung ist die Reflexion zu verwenden, um die Eigenschaften zu erhalten

using System;
using System.Collections.Generic;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            var anonymous = p.GetList(new[]{
                new { Id = 1, Name = "Foo" },       
                new { Id = 2, Name = "Bar" }
            });

            p.WriteList(anonymous);
        }

        private List<T> GetList<T>(params T[] elements)
        {
            var a = TypeGenerator(elements);
            return a;
        }

        public static List<T> TypeGenerator<T>(T[] at)
        {
            return new List<T>(at);
        }

        private void WriteList<T>(List<T> elements)
        {
            PropertyInfo[] pi = typeof(T).GetProperties();
            foreach (var el in elements)
            {
                foreach (var p in pi)
                {
                    Console.WriteLine("{0}", p.GetValue(el, null));
                }
            }
            Console.ReadLine();
        }
    }
}
var list = new[]{
new{
FirstField = default(string),
SecondField = default(int),
ThirdField = default(double)
}
}.ToList();
list.RemoveAt(0);

Sie können eine Liste der dynamischen erstellen.

List<dynamic> anons=new List<dynamic>();
foreach (Model model in models)
{
   var anon= new
   {
      Id = model.Id,
      Name=model.Name
   };
   anons.Add(anon);
}

„dynamisch“ wird durch den ersten Wert initialisiert hinzugefügt.

Sie können es auf diese Weise tun:

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 ein wenig „Hacky“ zu mir, aber es funktioniert -., Wenn Sie wirklich eine Liste haben müssen und nicht nur die anonyme Array verwenden

Dies ist eine alte Frage, aber ich dachte, dass ich in meiner C # 6 Antwort setzen würde. Ich muss oft Testdaten einzurichten, die sich leicht in-Code als eine Liste von Tupeln eingegeben wird. Mit ein paar Erweiterungsfunktionen ist es möglich, dieses schöne, kompakte Format zu haben, ohne auf jeden Eintrag den Namen 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 });

Das gibt eine IEnumerable - wenn Sie eine Liste, die Sie dann nur noch hinzufügen ToList hinzufügen ()

.

Die Magie kommt von benutzerdefinierter 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 Ich mag nicht wissen, ist, dass die Typen von den Namen getrennt werden, aber wenn Sie wirklich nicht wollen, eine neue Klasse machen, dann wird dieser Ansatz noch können Sie lesbare Daten haben.

Für Ihr zweites Beispiel, wo Sie eine neue List<T> zu initialisieren haben, eine Idee ist eine anonyme Liste zu erstellen, und dann deaktivieren Sie es.

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

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

oder als Erweiterung Methode soll 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 noch kürzer,

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

diese Antwort , kam ich mit zwei Methoden auf, die die Aufgabe tun könnte:

    /// <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 Methoden verwenden wie

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

Diese Antwort eine ähnliche Idee hat, aber ich habe es nicht gesehen, bis, nachdem ich diese Methoden gemacht.

Versuchen Sie mit diesem:

var result = new List<object>();

foreach (var test in model.ToList()) {
   result.Add(new {Id = test.IdSoc,Nom = test.Nom});
}
static void Main()
{
    List<int> list = new List<int>();
    list.Add(2);
    list.Add(3);
    list.Add(5);
    list.Add(7);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top