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

前端 未结 9 1698
有刺的猬
有刺的猬 2021-01-30 05:25

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

        
相关标签:
9条回答
  • 2021-01-30 05:47

    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.


    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:

    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:

    var myList = GetEmptyListWithAnonType(new { AttackingTank = default(Tank), TargetTank = default(Tank), });
    
    0 讨论(0)
  • 2021-01-30 05:50

    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) });
    
    0 讨论(0)
  • 2021-01-30 05:52

    It's worth to note that finally, there is possibility to use such syntax. It had been introduced in 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;
    
    0 讨论(0)
  • 2021-01-30 05:57

    How about 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);
    
    0 讨论(0)
  • 2021-01-30 05:58

    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});
    
    0 讨论(0)
  • 2021-01-30 05:59

    You could just have a generic method that takes a params and returns it:

    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}
    );
    
    0 讨论(0)
提交回复
热议问题