创建匿名类型的通用列表有诀窍吗?

Oop*_*ser 37 c# generics anonymous-types

有时我需要使用一个元组,例如我有坦克和他们的目标坦克列表(他们追逐他们或类似的东西):

List<Tuple<Tank,Tank>> mylist = new List<Tuple<Tank,Tank>>();
Run Code Online (Sandbox Code Playgroud)

然后当我遍历列表时,我访问它们

mylist[i].item1 ...
mylist[i].item2 ...
Run Code Online (Sandbox Code Playgroud)

这是非常令人困惑的,我总是忘记什么是item1和什么是item2,如果我可以通过以下方式访问它们:

mylist[i].AttackingTank...
mylist[i].TargetTank...
Run Code Online (Sandbox Code Playgroud)

它会更清楚,有没有办法在没有定义类的情况下完成它:

MyTuple
{
public Tank AttackingTank;
public Tank TargetTank;
}
Run Code Online (Sandbox Code Playgroud)

我想避免定义这个类,因为那时我将不得不在不同的场景中定义许多不同的类,我可以做一些"技巧"并使这个匿名.

就像是 :

var k = new {Name = "me", phone = 123};
mylist.Add(k);
Run Code Online (Sandbox Code Playgroud)

当然,我定义它时没有类型传递给List的问题

ale*_*lex 94

您可以为匿名类型创建一个空列表,然后使用它,享受完整的智能感知和编译时检查:

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);
Run Code Online (Sandbox Code Playgroud)


Hac*_*ese 17

你可以用一个List<dynamic>.

 var myList = new List<dynamic>();
 myList.Add(new {Tank = new Tank(), AttackingTank = new Tank()});

 Console.WriteLine("AttackingTank: {0}", myList[0].AttackingTank);
Run Code Online (Sandbox Code Playgroud)


Jep*_*sen 7

这是一个黑客:

var myList = Enumerable.Empty<int>()
    .Select(dummy => new { AttackingTank = default(Tank), TargetTank = default(Tank), })
    .ToList();
Run Code Online (Sandbox Code Playgroud)

如果Tank是类类型,则可以编写(Tank)null而不是default(Tank).您也可以使用Tank碰巧有的实例.


编辑:

要么:

var myList = Enumerable.Repeat(
    new { AttackingTank = default(Tank), TargetTank = default(Tank), },
    0).ToList();
Run Code Online (Sandbox Code Playgroud)

如果您制作通用方法,则不必使用Enumerable.Empty.它可能是这样的:

static List<TAnon> GetEmptyListWithAnonType<TAnon>(TAnon dummyParameter)
{
    return new List<TAnon>();
}
Run Code Online (Sandbox Code Playgroud)

TAnon当然,它可以通过使用推断来调用,如:

var myList = GetEmptyListWithAnonType(new { AttackingTank = default(Tank), TargetTank = default(Tank), });
Run Code Online (Sandbox Code Playgroud)


Puc*_*acz 7

值得注意的是,最后,有可能使用这样的语法.它已在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;
Run Code Online (Sandbox Code Playgroud)


Sea*_*ean 5

你可以只使用一个泛型方法来获取params并返回它:

public static IList<T> ToAnonymousList<T>(params T[] items)
{
  return items;
}
Run Code Online (Sandbox Code Playgroud)

所以现在你可以说:

var list=ToAnonymousList
(
  new{A=1, B=2},
  new{A=2, B=2}
);
Run Code Online (Sandbox Code Playgroud)