1

我是 C# 的新手,我想在最近的一个项目中使用匿名类型,但我遇到了一个需要你帮助的困惑问题。我一开始使用 object[],但出现错误。代码如下所示:

        List<object> f = new List<object>(); 
        f.Add(new { Name = 1, Age = 31 });
        f.Add(new { Name = 2, Age = 31 });
        f.Add(new { Name = 3, Age = 4 });
        f.Add(new { Name = 4, Age = 1 });
        f.Add(new { Name = 5, Age = 1 });
        var a = f[0].Age; // no use

但是这段代码很有用:</p>

    var f = new []
    {
        new { Name = 1, Age = 31 },
        new { Name = 2, Age = 31 },
        new { Name = 3, Age = 4 },
        new { Name = 4, Age = 1 },
        new { Name = 5, Age = 1 }
    };
    var a = f[0].Age; 

我只想使用匿名类型的列表并访问它的成员。我的方法有什么问题,我应该怎么做才能实现我的目标?

4

3 回答 3

5

Object没有Age财产。因此,第一种方法无法编译,因为您已将匿名类型装箱为对象。

第二个有效,因为编译器知道它是哪种(匿名)类型。

您不能在当前方法之外使用匿名类型。因此,我建议使用具体类型。

class Person
{
    public int Age{ get;set; }
    public string Name{ get;set; }
}

现在使用它:

var f = new List<Person>(){
             new Person{ Name = "1", Age = 31 },
             new Person{ Name = "2", Age = 31 },
             new Person{ Name = "3", Age = 4 },
             new Person{ Name = "4", Age = 1 },
             new Person{ Name = "5", Age = 1 }
};
var a = f[0].Age;
于 2012-12-29T11:34:50.327 回答
2

编辑- 更新的答案。原始答案在最后。

以下不起作用

List<object> f = new List<object>(); 

因为对象没有Age属性。

要获取 Age 属性,您需要将类型转换为具体类型。但是由于您使用了匿名类型,因此您在编码时没有具体类型(因此您无法转换它)。

另一种(不鼓励的)替代方法是使用reflection

 PropertyInfo[] properties = f[0].GetType().GetProperties();
 var ageProperty = properties.First (x=> x.Name == "Age");
 var a = ageProperty.GetValue (f[0],null); // no use    

另一种选择(如果是 .NET 4.0 及更高版本)是使用关键字dynamic.

   dynamic obj = f[0];
   int age = obj.Age;
   Console.WriteLine(age); // prints 31

原始答案

改变

object[] f = new object[]

 var f = new []

第一个会起作用。

于 2012-12-29T11:34:25.760 回答
0

一个问题是因为您使用的是匿名类型(但也许这没关系,因为您首先尝试使用它们)您实际上无法声明或传递此列表(您如何声明List<SomeAnonymousTypeThatDoesNotHaveAName>?)

您可以通过利用泛型类型推断和使用泛型和作弊var

public List<T> BuildList<T>(params T[] entries)
{
    return new List<T>(entries);
}

当您BuildList再次调用 时,因为它们是匿名类型,您无法显式分配<T>,但您可以让类型推断处理它!

var list = BuildList(
    new { Name = 1, Age = 31 },
    new { Name = 2, Age = 31 },
    new { Name = 3, Age = 4 },
    new { Name = 4, Age = 1 },
    new { Name = 5, Age = 1 });

类型推断可以很好地处理匿名类型并构建您的列表!

Console.WriteLine(list.Count); //5
Console.WriteLine(list[0].Name + ", " + list[0].Age); //1, 31
Console.WriteLine(list.GetType().FullName); //System.Collections.Generic.List`1[[<>f__AnonymousType0`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], query_jyattd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]

编辑:更好的是做一个扩展方法!

public static class ArrayExtensions
{
    public static List<T> MakeAnonymousList<T>(this T[] entries)
    {
        return new List<T>(entries);
    }
}

然后你可以像这样使用它:

var list = new[] {
    new { Name = 1, Age = 31 },
    new { Name = 2, Age = 31 },
    new { Name = 3, Age = 4 },
    new { Name = 4, Age = 1 },
    new { Name = 5, Age = 1 }}
    .MakeAnonymousList();

编辑:很酷的事情是你有一个完整的功能List<T>,你可以添加/删除/Linq。添加项目必须使用相同的参数和顺序:

list.Add(new { Name = 6, Age = 2 }); //OK
list.Add(new { Age = 2, Name = 6 }); //compile error!


var maxAge = list.Max(person => person.Age);
var oldPerson = list.Where(person => person.Age == maxAge).First();
Console.WriteLine(maxAge); //31
Console.WriteLine(oldPerson.Name + ", " + oldPerson.Age); //1, 31

智能感知也很好用!

于 2012-12-29T12:19:12.290 回答