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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:50:43  来源:igfitidea点击:

Is there a trick in creating a generic list of anonymous type?

c#genericsanonymous-types

提问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 Tankis a class type, you can write (Tank)nullinstead of default(Tank). You can also use some Tankinstance 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 TAnoninferred 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 paramsand 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});