为什么我不能在C#中创建匿名类型的列表<T>?

3 c# list anonymous-types .net-core

我是新来anonymous types的C#,我想创建一个listanonymous types包含3个变量:string strint numDataTime time

但是,当我尝试使用此问题的答案中的代码时: 匿名类的一般列表 对我不起作用。

我使用了一种简单的方法Console application,但我认为我得到了错误,因为我没有,System.Core因为有人在上述问题的评论中说:

(当然,您还需要引用System.Core。)

我不知道是什么System.Core,如果有的话,可能是问题所在

我使用Systme.Linq

这是代码:

var list = new[] { str, num, time }.ToList();
list.add("hi", 5, DateTime.Now);

Console.WriteLine(list[0].num);
Run Code Online (Sandbox Code Playgroud)

我也遇到问题时,我试图指定typevariables 例如string str

pin*_*x33 6

您缺少某些语法。匿名类型必须使用声明new{...}当不能通过变量名称推断属性名称时,必须声明属性名称(您也输入错了Add;应该是大写)。

以下作品

var str = "string";
var num = 5;
var time = DateTime.UtcNow;
// notice double "new" 
// property names inferred to match variable names
var list = new[] { new { str, num, time } }.ToList(); 

// "new" again. Must specify property names since they cannot be inferred
list.Add(new { str = "hi", num = 5, time = DateTime.Now });

Console.WriteLine(list[0].num);
Run Code Online (Sandbox Code Playgroud)

话虽如此,这很笨拙。我建议编写一个具有所需属性的类,或使用ValueTuple

有效并且更清晰/更干净:

var list = new List<(string str, int num, DateTime time)>();

// ValueTuple are declared in parens, method calls require parens as well
// so we end up with two sets of parens, both required 
list.Add((str, num, time));
list.Add(("hi", 5, DateTime.Now));

Console.WriteLine(list[0].num);
Run Code Online (Sandbox Code Playgroud)

喜欢您自己的类的另一个原因ValueTuple是,您不能将方法声明为接受匿名类型。换句话说,这样的东西是无效的:

public void DoSomethingWithAnonTypeList(List<???> theList ) { ... } 
Run Code Online (Sandbox Code Playgroud)

没有任何内容*我可以替换掉,???因为匿名类型都是匿名的,internal并且具有“无法说”的名称。您将无法传递列表并对其进行有意义的操作。那有什么意义呢?

相反,我可以将方法声明为接受ValueTuples 的列表:

public void DoSomethingWithTupleList(List<(string, int, DateTime)> theList) { 
     Console.WriteLine(theList[0].Item1);
} 
Run Code Online (Sandbox Code Playgroud)

或使用命名元组:

public void DoSomethingWithTupleList(List<(string str, int num, DateTime time)> theList) { 
     Console.WriteLine(theList[0].time);
} 
Run Code Online (Sandbox Code Playgroud)

*从技术上讲,您可以将匿名类型列表传递给通用方法。但是,您将无法访问各个属性。您能做的最好的事情是访问列表Count或遍历列表/可枚举,也许打印默认值ToString,实际上也不会给您带来太多好处。这里没有通用的约束可以提供帮助。此方法中的第三条语句将生成编译器错误

public void DoSomethingGenerically<T>(List<T> theList) {

      Console.WriteLine(theList.Count); // valid
      Console.WriteLine(theList[0]); // valid, prints default ToString

      Console.WriteLine(theList[0].num); // invalid! What's the point?

}

var list = new[] { new { str = "hi", num = 5, time = DateTime.Now } }.ToList();
// valid due to type inference, but see comments above
DoSomethingGenerically(list); 
Run Code Online (Sandbox Code Playgroud)

请注意,您会遇到与相同的问题ValueTuple,我只是在澄清我的“不做任何事情”的声明。