Question

En C # 3.0, vous pouvez créer une classe anonyme avec la syntaxe suivante

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

Existe-t-il un moyen d'ajouter ces classes anonymes à une liste générique?

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

Un autre exemple:

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

while (....)
{
    ....
    list.Add(new {Id = x, Name = y});
    ....
}
Était-ce utile?

La solution

Vous pourriez faire:

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

Il existe de nombreuses façons de dépouiller ce chat, mais fondamentalement, ils utiliseront tous l'inférence de type quelque part - ce qui signifie que vous devez appeler une méthode générique (éventuellement en tant que méthode d'extension). Un autre exemple pourrait être:

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

var list = CreateList(o, o1);

Vous avez l'idée:)

Autres conseils

Voici la réponse.

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

Il existe de nombreuses façons de procéder, mais certaines des réponses présentées ici créent une liste contenant des éléments parasites, ce qui nécessite de la vider de la liste.

Si vous recherchez une liste vide du type générique, utilisez un sélecteur sur une liste de nuplets pour créer la liste vide. Aucun élément ne sera instancié.

Voici le one-liner pour créer une liste vide:

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

Vous pouvez ensuite y ajouter votre type générique:

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

Comme alternative, vous pouvez faire quelque chose comme ci-dessous pour créer la liste vide (mais je préfère le premier exemple car vous pouvez également l'utiliser pour une collection remplie de Tuples):

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

Pas exactement, mais vous pouvez dire List<object> et tout ira bien. Cependant, list[0].Id ne fonctionnera pas.

Cela fonctionnera au moment de l'exécution en C # 4.0 avec un List<dynamic>, c'est-à-dire que vous n'obtiendrez pas IntelliSense.

Je suppose

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

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

fonctionnera.

Vous pourriez aussi envisager de l'écrire comme ceci:

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

J'utilise habituellement ce qui suit: principalement parce que vous avez alors & "Démarrer" & "; avec une liste vide.

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

Dernièrement, je l’écris à la place:

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

L’utilisation de la méthode de répétition vous permettrait également de faire:

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

.. qui vous donne la liste initiale avec le premier élément déjà ajouté.

Vous pouvez le faire dans votre code.

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

J'ai vérifié l'IL sur plusieurs réponses. Ce code fournit efficacement une liste vide:

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

Dans la dernière version 4.0, pouvez utiliser dynamique comme ci-dessous

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

Voici ma tentative.

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

Je l'ai trouvé lorsque j'ai écrit quelque chose de similaire pour créer une liste anonyme pour un type personnalisé.

Voici une autre méthode de création d'une liste de types anonymes qui vous permet de commencer avec une liste vide, tout en ayant toujours accès à IntelliSense.

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

Si vous souhaitez conserver le premier élément, il vous suffit de mettre une lettre dans la chaîne.

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

Au lieu de ceci:

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

Vous pouvez faire ceci:

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

Cependant, vous obtiendrez une erreur de compilation si vous essayez d'effectuer une opération similaire dans un autre domaine, bien que cela fonctionne à l'exécution:

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

Le problème est que seuls les membres de Object sont disponibles au moment de l'exécution, même si intellisense affichera les propriétés id et nom .

Dans .net 4.0, une solution consiste à utiliser le mot clé dynamique à la place de objet dans le code ci-dessus.

Une autre solution consiste à utiliser la réflexion pour obtenir les propriétés

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

Vous pouvez créer une liste de dynamiques.

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

" dynamique " est initialisé par la première valeur ajoutée.

Vous pouvez le faire de cette façon:

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

Il semble un peu & "hacky &"; pour moi, mais cela fonctionne - si vous avez vraiment besoin d'une liste et que vous ne pouvez pas simplement utiliser le tableau anonyme.

C’est une vieille question, mais je pensais que je mettrais ma réponse C # 6. Je dois souvent configurer des données de test faciles à saisir dans le code sous forme de liste de n-uplets. Avec quelques fonctions d’extension, il est possible d’avoir ce joli format compact sans répéter les noms sur chaque entrée.

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

Ceci donne un IEnumerable - si vous voulez une liste que vous pouvez ajouter, ajoutez simplement ToList ().

La magie vient de l'extension personnalisée Ajoutez des méthodes pour les nuplets, comme décrit à l'adresse 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...

}

La seule chose que je n’aime pas, c’est que les types sont séparés des noms, mais si vous ne voulez vraiment pas créer une nouvelle classe, cette approche vous laissera quand même des données lisibles.

Pour votre deuxième exemple, où vous devez initialiser un nouveau List<T>, une idée consiste à créer une liste anonyme, puis à l'effacer.

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

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

Ou comme méthode d'extension, cela devrait être plus simple:

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

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

Ou probablement même plus court,

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

Dérivant de cette réponse , j'ai proposé deux méthodes pour effectuer cette tâche:

    /// <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>();
    }

Vous pouvez utiliser des méthodes telles que

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

Cette réponse a une idée similaire, mais je ne l'ai pas vue avant d'avoir créé ces méthodes.

Essayez avec ceci:

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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top