C# 创建匿名类型的通用列表有技巧吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15749445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a trick in creating a generic list of anonymous type?
提问by OopsUser
Sometimes i need to use a Tuple, for example i have list of tanks and their target tanks (they chase after them or something like that ) :
有时我需要使用元组,例如我有坦克列表和他们的目标坦克(他们追逐他们或类似的东西):
List<Tuple<Tank,Tank>> mylist = new List<Tuple<Tank,Tank>>();
and then when i iterate over the list i access them by
然后当我遍历列表时,我通过
mylist[i].item1 ...
mylist[i].item2 ...
It's very confusing and i always forget what is item1 and what is item2, if i could access them by :
这非常令人困惑,我总是忘记什么是 item1 什么是 item2,如果我可以通过以下方式访问它们:
mylist[i].AttackingTank...
mylist[i].TargetTank...
It would be much clearer, is there a way to do it without defining a class:
会更清楚,有没有办法在不定义类的情况下做到这一点:
MyTuple
{
public Tank AttackingTank;
public Tank TargetTank;
}
I want to avoid defining this class because then i would have to define many different classes in different scenarios, can i do some "trick" and make this anonymous.
我想避免定义这个类,因为那样我将不得不在不同的场景中定义许多不同的类,我可以做一些“技巧”并使这个匿名。
Something like :
就像是 :
var k = new {Name = "me", phone = 123};
mylist.Add(k);
The problem of course that i don't have a type to pass to the List when i define it
当然,当我定义 List 时,我没有传递给 List 的类型的问题
采纳答案by alex
You can create an empty list for anonymous types and then use it, enjoying full intellisense and compile-time checks:
您可以为匿名类型创建一个空列表,然后使用它,享受完整的智能感知和编译时检查:
var list = Enumerable.Empty<object>()
.Select(r => new {A = 0, B = 0}) // prototype of anonymous type
.ToList();
list.Add(new { A = 4, B = 5 }); // adding actual values
Console.Write(list[0].A);
回答by moribvndvs
You could use a List<dynamic>
.
你可以使用一个List<dynamic>
.
var myList = new List<dynamic>();
myList.Add(new {Tank = new Tank(), AttackingTank = new Tank()});
Console.WriteLine("AttackingTank: {0}", myList[0].AttackingTank);
回答by Dmytro
How about ExpandoObject?
ExpandoObject怎么样?
dynamic tuple = new ExpandoObject();
tuple.WhatEverYouWantTypeOfTank = new Tank(); // Value of any type
EDITS:
编辑:
dynamic tuple = new ExpandoObject();
tuple.AttackingTank = new Tank();
tuple.TargetTank = new Tank();
var mylist = new List<dynamic> { tuple };
//access to items
Console.WriteLine(mylist[0].AttackingTank);
回答by Jeppe Stig Nielsen
Here's a hack:
这是一个黑客:
var myList = Enumerable.Empty<int>()
.Select(dummy => new { AttackingTank = default(Tank), TargetTank = default(Tank), })
.ToList();
If Tank
is a class type, you can write (Tank)null
instead of default(Tank)
. You can also use some Tank
instance you happen to have at hand.
如果Tank
是类类型,则可以编写(Tank)null
代替default(Tank)
. 您还可以使用Tank
您手头碰巧拥有的一些实例。
EDIT:
编辑:
Or:
或者:
var myList = Enumerable.Repeat(
new { AttackingTank = default(Tank), TargetTank = default(Tank), },
0).ToList();
If you make a generic method, you won't have to use Enumerable.Empty
. It could go like this:
如果您创建通用方法,则不必使用Enumerable.Empty
. 它可以是这样的:
static List<TAnon> GetEmptyListWithAnonType<TAnon>(TAnon dummyParameter)
{
return new List<TAnon>();
}
It is to be called with the TAnon
inferred from usage, of course, as in:
将使用TAnon
从用法推断出来的方法调用它,当然,如下所示:
var myList = GetEmptyListWithAnonType(new { AttackingTank = default(Tank), TargetTank = default(Tank), });
回答by Sean
You could just have a generic method that takes a params
and returns it:
您可以只拥有一个接受 aparams
并返回它的通用方法:
public static IList<T> ToAnonymousList<T>(params T[] items)
{
return items;
}
So now you can say:
所以现在你可以说:
var list=ToAnonymousList
(
new{A=1, B=2},
new{A=2, B=2}
);
回答by Overfilledwaistcoat
Or even more simple
或者更简单
var tupleList = (
new[] {
new { fruit = "Tomato", colour = "red"},
new { fruit = "Tomato", colour = "yellow"},
new { fruit = "Apple", colour = "red"},
new { fruit = "Apple", colour = "green"},
new { fruit = "Medlar", colour = "russet"}
}).ToList();
Which loses the static function.
这失去了静态功能。
回答by rrreee
Just to add one more handy bit here. I use Alex's answer on occasion, but it drives me a bit nuts trying to track it back down when I need it, since it's not obvious (I find myself searching for "new {").
只是在这里添加一个方便的位。我有时会使用亚历克斯的答案,但是当我需要它时,它让我有点发疯,因为它并不明显(我发现自己在寻找“新的{”)。
So I added the following little static method (I wish I could make it an extension method, but of what type?):
所以我添加了以下小的静态方法(我希望我可以把它变成一个扩展方法,但是是什么类型的?):
public static List<T> CreateEmptyListOf<T>(Func<T> itemCreator)
{
return Enumerable
.Empty<object>()
.Select(o => itemCreator())
.ToList();
}
This isolates the part that is different each time I need this pattern from those that are the same. I call it like this:
这将每次我需要此模式时不同的部分与相同的部分隔离开来。我这样称呼它:
var emptyList = Ext.CreateEmptyListOf(() => new { Name = default(string), SomeInt = default(int) });
回答by Puchacz
It's worth to note that finally, there is possibility to use such syntax. It had been introduced in C# 7.0
值得注意的是,最后,有可能使用这种语法。它已在 C# 7.0 中引入
var tanks = new List<(Tank AttackingTank, Tank TargetTank)>();
(Tank, Tank) tTank = (new Tank(), new Tank());
tanks.Add(tTank);
var a = tanks[0].AttackingTank;
var b = tanks[0].TargetTank;
回答by Elion Limanaj
You can create a list of objects:
您可以创建对象列表:
List<object> myList = new List<object>();
Then add the anonymous type to your list:
然后将匿名类型添加到您的列表中:
myList.Add(new {Name = "me", phone = 123});