当前位置:  开发笔记 > 编程语言 > 正文

匿名类的通用列表

如何解决《匿名类的通用列表》经验,为你挑选了15个好方法。

在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 list = new List();
list.Add(o);
list.Add(o1);

另一个例子:

List list = new List();

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

Jon Skeet.. 411

你可以这样做:

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

有很多方法可以为这只猫设置皮肤,但基本上它们都会在某处使用类型推断 - 这意味着你必须调用泛型方法(可能作为扩展方法).另一个例子可能是:

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

var list = CreateList(o, o1);

你明白了:)



1> Jon Skeet..:

你可以这样做:

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

有很多方法可以为这只猫设置皮肤,但基本上它们都会在某处使用类型推断 - 这意味着你必须调用泛型方法(可能作为扩展方法).另一个例子可能是:

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

var list = CreateList(o, o1);

你明白了:)


@DHornpout:这会给出一个数组,而不是List .
@DHornpout:你有"使用System.Linq;" 在你的文件的顶部?ToList是一个LINQ运算符.
(当然,您还需要对System.Core的引用.)
得到它..需要包括"使用System.Linq".谢谢.
在Visual Studio中看起来似乎不一致,智能感知在发现缺少包含引用扩展方法的程序集(与引用类型相同)方面没有多大帮助.
这个男人到处都是,今天搜了8个问题,7回答他.

2> 小智..:

这是答案.

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


Dutt,你的代码应该在没有.ToList()的情况下工作.
好吧,现在我们需要一个用select语句替换new {}行的例子.var list = sourceList.Select(o => new {o.ModelId,o.PartNumber,o.Quantity}).ToList();

3> 小智..:

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

如果要查找泛型类型的空列表,请使用"针对元组列表选择"来创建空列表.不会实例化任何元素.

这是创建空列表的单线程:

 var emptyList = new List>()
          .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()
          .Select(t => new { Id = default(int), Name = default(string) }).ToList();   



4> Jeff Moser..:

不完全是,但你可以说List,事情会奏效.但是,list[0].Id不会起作用.

这将在运行时在C#4.0中通过拥有一个List,即你将无法获得IntelliSense.


这是我担心人们会用动态做的事情.
我没有说这是一个很棒的想法,但它有可能:-)例如,可能需要从Ruby存储对象.
但是在这些情况下,源类型毕竟是动态的,对于匿名类型使用List 是没有意义的.

5> erikkallen..:

我猜

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

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



6> Rostov..:

我通常使用以下内容; 主要是因为你然后用一个空的列表"开始".

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

使用repeat方法还可以执行以下操作:

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

..which为您提供已添加的第一个项目的初始列表.


您不需要以空列表开头 - 您可以执行Range(0,1)并使select语句中的第一个对象成为第一个对象.

7> 小智..:

您可以在代码中执行此操作.

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



8> MEC..:

我在几个答案上检查了IL.此代码有效地提供了一个空列表:

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



9> 小智..:

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

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



10> user_v..:

这是我的尝试.

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


当我为自定义类型制作匿名列表时,我想出了类似的东西.



11> 小智..:

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

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

如果你想保留第一个项目,只需在字符串中放一个字母.

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



12> Code Name Ja..:

您可以创建一个动态列表。

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

“动态”通过添加的第一个值进行初始化。



13> 小智..:

而不是这个:

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

List  list = new List(); 
list.Add(o); 
list.Add(o1);

你可以这样做:

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

List list = new List(); 
list.Add(o); 
list.Add(o1);


但是,如果您尝试在另一个范围内执行此类操作,则会遇到编译时错误,尽管它在运行时有效:

private List GetList()
{ 
    List list = new List();
    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); 
    }
}


问题是只有Object的成员在运行时可用,尽管intellisense将显示属性idname.

在.net 4.0中,解决方案是在上面的代码中使用关键字dynamic istead of object.

另一种解决方案是使用反射来获取属性

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 GetList(params T[] elements)
        {
            var a = TypeGenerator(elements);
            return a;
        }

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

        private void WriteList(List 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();
        }
    }
}



14> 小智..:
var list = new[]{
new{
FirstField = default(string),
SecondField = default(int),
ThirdField = default(double)
}
}.ToList();
list.RemoveAt(0);



15> 小智..:

这是一个老问题,但是我想我应该填写C#6答案。我经常必须设置易于在代码中以元组列表形式输入的测试数据。有了几个扩展功能,就可以拥有这种精巧紧凑的格式,而无需在每个条目上重复名称。

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

这提供了IEnumerable-如果您想要可以添加到的列表,则只需添加ToList()。

魔术来自用于元组的自定义扩展Add方法,如/sf/ask/17360801/所述。

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

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

// and so on...

}

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

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有