代码之家  ›  专栏  ›  技术社区  ›  DHornpout

匿名类的通用列表

  •  478
  • DHornpout  · 技术社区  · 16 年前

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

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

    List<var> list = new List<var>();
    
    while (....)
    {
        ....
        list.Add(new {Id = x, Name = y});
        ....
    }
    
    22 回复  |  直到 12 年前
        1
  •  464
  •   Jon Skeet    16 年前

    你可以这样做:

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

    public static List<T> CreateList<T>(params T[] elements)
    {
         return new List<T>(elements);
    }
    
    var list = CreateList(o, o1);
    

        2
  •  115
  •   Paul Bellora    13 年前

    答案如下。

    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);
    
        3
  •  72
  •   Paul Rouleau    10 年前

    有很多方法可以做到这一点,但这里的一些响应是创建一个包含垃圾元素的列表,这需要您清除列表。

    如果您正在查找泛型类型的空列表,请对元组列表使用Select来创建空列表。不会实例化任何元素。

    下面是创建空列表的一行代码:

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

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

     var emptyList = new List<object>()
              .Select(t => new { Id = default(int), Name = default(string) }).ToList();   
    
        4
  •  49
  •   Micha Wiedenmann Lieven Keersmaekers    9 年前

    List<object> list[0].Id 不会工作。

    在运行时 在C#4.0中,通过使用 List<dynamic>

        5
  •  24
  •   Luis Perez    13 年前

    如果你使用的是C#7或更高版本,你可以使用 tuple types 而不是匿名类型。

    var myList = new List<(int IntProp, string StrProp)>();
    myList.Add((IntProp: 123, StrProp: "XYZ"));
    
        6
  •  23
  •   Rostov    9 年前

    我猜

    List<T> CreateEmptyGenericList<T>(T example) {
        return new List<T>();
    }
    
    void something() {
        var o = new { Id = 1, Name = "foo" };
        var emptyListOfAnonymousType = CreateEmptyGenericList(o);
    }
    

    将工作。

    void something() {
        var String = string.Emtpy;
        var Integer = int.MinValue;
        var emptyListOfAnonymousType = CreateEmptyGenericList(new { Id = Integer, Name = String });
    }
    
        7
  •  20
  •   MalachiteBR    12 年前

    我通常使用以下内容:;主要是因为你从一个空的列表“开始”。

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

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

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

        8
  •  19
  •   Bassem    5 年前

    var list = new[] { new { Id = 1, Name = "Foo" } }.ToList();
    list.Add(new { Id = 2, Name = "Bar" });
    
        9
  •  14
  •   Damith Asanka    8 年前

    我检查了几个答案的IL。这段代码有效地提供了一个空列表:

        using System.Linq;
        …
        var list = new[]{new{Id = default(int), Name = default(string)}}.Skip(1).ToList();
    
        10
  •  12
  •   MEC    9 年前

    在最新版本4.0中,可以使用动态,如下所示

    var list = new List<dynamic>();
            list.Add(new {
                Name = "Damith"
        });
            foreach(var item in list){
                Console.WriteLine(item.Name);
            }
        }
    
        11
  •  10
  •   Code Name Jack    7 年前

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

        12
  •  8
  •   user_v    14 年前

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

    当我为自定义类型创建匿名列表时,我写了类似的东西。

        13
  •  8
  •   Tom Dee    6 年前

    这是另一种创建匿名类型列表的方法,允许您从空列表开始,但仍然可以访问IntelliSense。

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

    var items = "1".Select( t => new {Id = 1, Name = "foo"} ).ToList();
    
        14
  •  7
  •   Brackus    11 年前

    var list = new List<dynamic>() 
    { 
        new { Id = 1, Name = "Foo" }, 
        new { Id = 2, Name = "Bar" } 
    };
    

    您始终可以使用 object 而不是 dynamic 动态的 更有意义。

        15
  •  6
  •   Jon Skeet    16 年前

    取而代之的是:

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

    你可以这样做:

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

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

    .

    在.net 4.0中,解决方案是使用关键字 动态的

    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();
            }
        }
    }
    
        16
  •  6
  •   Paul Bellora    13 年前

    你可以这样做:

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

        17
  •  5
  •   morlock    13 年前

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

    魔术来自元组的自定义扩展Add方法,如所述 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...
    

    }

    我唯一不喜欢的是类型与名称是分开的,但如果你真的不想创建一个新类,那么这种方法仍然可以让你获得可读的数据。

        18
  •  5
  •   Community CDub    8 年前
    var list = new[]{
    new{
    FirstField = default(string),
    SecondField = default(int),
    ThirdField = default(double)
    }
    }.ToList();
    list.RemoveAt(0);
    
        19
  •  3
  •   nawfal Donny V.    9 年前

    对于您的第二个示例,您必须初始化一个新的 List<T>

    var list = new[] { o, o1 }.ToList();
    list.Clear();
    
    //and you can keep adding.
    while (....)
    {
        ....
        list.Add(new { Id = x, Name = y });
        ....
    }
    

    public static List<T> GetEmptyListOfThisType<T>(this T item)
    {
        return new List<T>();
    }
    
    //so you can call:
    var list = new { Id = 0, Name = "" }.GetEmptyListOfThisType();
    

    或者可能更短,

    var list = new int[0].Select(x => new { Id = 0, Name = "" }).Tolist();
    
        20
  •  1
  •   Sir Intellegence-BrainStormexe    6 年前

    来源于 this answer ,我提出了两种可以完成这项任务的方法:

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

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

    This answer 我也有类似的想法,但直到我做了这些方法之后我才看到它。

        21
  •  0
  •   Matteo Gariglio    11 年前

    使用反射

    documentation

    using System;
    using System.Collections;
    using System.Collections.Generic;
    
    var anonObj = new { Id = 1, Name = "Foo" };
    var anonType = anonObj.GetType();
    
    var listType = typeof(List<>);
    
    // We know that List<> have only one generic argument, so we do this:
    var contructed = listType.MakeGenericType(anonType);
    
    // Create instance
    var instance = Activator.CreateInstance(contructed);
    
    // Using it
    var list = (IList)instance;
    list.Add(anonObj);
    

    Dictionary<,>
    前任。: dicType.MakeGenericType( type1, type2 )

    对于具有约束的泛型类型( where T : struct 我们需要做更多的验证。查看microsoft文档以了解如何操作。

        22
  •  -14
  •   Steve Czetty Wilko van der Veen    13 年前

    var result = new List<object>();
    
    foreach (var test in model.ToList()) {
       result.Add(new {Id = test.IdSoc,Nom = test.Nom});
    }
    
    推荐文章