سؤال

في C# 3.0 ، يمكنك إنشاء فئة مجهولة المصدر مع بناء الجملة التالي

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});
    ....
}
هل كانت مفيدة؟

المحلول

يمكنك أن تفعل:

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

انت وجدت الفكرة :)

نصائح أخرى

ها هو الجواب.

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

هناك العديد من الطرق للقيام بذلك ، لكن بعض الردود هنا تقوم بإنشاء قائمة تحتوي على عناصر القمامة ، والتي تتطلب منك مسح القائمة.

إذا كنت تبحث عن قائمة فارغة من النوع العام ، فاستخدم تحديدًا مقابل قائمة من tuples لإنشاء القائمة الفارغة. لن يتم إنشاء أي عناصر.

إليك خط واحد لإنشاء قائمة فارغة:

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

كبديل ، يمكنك القيام بشيء مثل أدناه لإنشاء القائمة الفارغة (ولكن ، أفضل المثال الأول لأنه يمكنك استخدامه لمجموعة من tuples مكتظة بالسكان أيضًا):

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

ليس بالضبط ، ولكن يمكنك القول List<object> والأشياء ستعمل. لكن، list[0].Id لن تعمل.

هذا سيفي بالغرض في وقت التشغيل في C# 4.0 من خلال وجود ملف List<dynamic>, ، هذا هو أنك لن تحصل على Intellisense.

اعتقد

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

عادة ما أستخدم ما يلي ؛ أساسا لأنك "تبدأ" مع قائمة فارغة.

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

.. الذي يمنحك القائمة الأولية مع إضافة العنصر الأول بالفعل.

يمكنك القيام بذلك في الكود الخاص بك.

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

راجعت IL على عدة إجابات. يوفر هذا الرمز بكفاءة قائمة فارغة:

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

In latest version 4.0, can use dynamic like below

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

Here is my attempt.

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

I came up with this when I wrote something similar for making a Anonymous List for a custom type.

Here is a another method of creating a List of anonymous types that allows you to start with an empty list, but still have access to IntelliSense.

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

If you wanted to keep the first item, just put one letter in the string.

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

Instead of this:

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

You could do this:

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

However, you will get a compiletime error if you try to do something like this in another scope, although it works at runtime:

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

The problem is that only the members of Object are available at runtime, although intellisense will show the properties id and name.

In .net 4.0 a solution is to use the keyword dynamic istead of object in the code above.

Another solution is to use reflection to get the properties

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

You can create a list of dynamic.

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

"dynamic" gets initialized by the first value added.

You can do it this way:

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

It seems a little "hacky" to me, but it works - if you really need to have a list and can't just use the anonymous array.

This is an old question, but I thought I'd put in my C# 6 answer. I often have to set up test data that is easily entered in-code as a list of tuples. With a couple of extension functions, it is possible to have this nice, compact format, without repeating the names on each entry.

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

This gives an IEnumerable - if you want a list that you can add to then just add ToList().

The magic comes from custom extension Add methods for tuples, as described at 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...

}

The only thing I don't like is that the types are separated from the names, but if you really don't want to make a new class then this approach will still let you have readable data.

For your second example, where you have to initialize a new List<T>, one idea is to create an anonymous list, and then clear it.

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

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

Or as an extension method, should be easier:

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

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

Or probably even shorter,

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

Deriving from this answer, I came up with two methods that could do the task:

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

You can use the methods like

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

This answer has a similar idea, but I didn't see it until after I made those methods.

Try with this:

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);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top