为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
喵喵时光机 2023-07-09 16:44:19
我是 c# 新手anonymous types,我想创建一个包含 3 个变量的变量list:, , 。anonymous typesstring 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);当我尝试指定type例如 的variables 时,我也遇到问题string str。
查看完整描述

1 回答

?
阿晨1998

TA贡献2037条经验 获得超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);

话虽如此,这相当笨重。我建议编写一个具有您想要的属性的类,或者使用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);

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


public void DoSomethingWithAnonTypeList(List<???> theList ) { ... } 

没有什么*我可以用来替换,???因为匿名类型都是internal并且具有“难以形容的”名称。你将无法传递你的清单并用它做一些有意义的事情。那么有什么意义呢?


相反,我可以声明一个方法接受 s 列表ValueTuple:


public void DoSomethingWithTupleList(List<(string, int, DateTime)> theList) { 

     Console.WriteLine(theList[0].Item1);

或使用命名元组:


public void DoSomethingWithTupleList(List<(string str, int num, DateTime time)> theList) { 

     Console.WriteLine(theList[0].time);

* 从技术上讲,您可以将匿名类型列表传递给泛型方法。但是您将无法访问各个属性。您能做的最好的事情就是访问列表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); 

请注意,您也会遇到同样的问题ValueTuple,我只是澄清我的“什么也不做”声明。


查看完整回答
反对 回复 2023-07-09
  • 1 回答
  • 0 关注
  • 145 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信