object[] = object[] f = new object[]与var f = new[]的区别

本文关键字:object new 区别 var | 更新日期: 2023-09-27 17:50:00

我是c#的新手,我想在最近的一个项目中使用匿名类型,但是我面临一个困惑的问题,需要您的帮助。我首先使用对象[],但我得到一个错误。代码如下所示:

        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

但是下面的代码很有用:

    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; 

我只是想使用一个匿名类型的列表和访问它的成员。我的方法有什么问题,我应该做些什么来实现我的目标?

object[] = object[] f = new object[]与var f = new[]的区别

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;

EDIT -更新后的答案。原来的答案在最后。

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 []

和第一个都可以。

一个问题是,因为你正在使用匿名类型(但也许这是好的,因为你试图在第一个地方使用它们),你实际上不能声明或传递这个列表(你如何声明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

智能感知也很好!