How to save anonymous type variables in to a collection?

    3 answers 3

    Depends on what is supposed to do next with the collection.

    If the collection is a temporary object, then work with it can be carried out in a generalized method (of course, the collection itself will also have an anonymous type outside):

    static List<T> CreateCollection<T>(T item) { return new List<T> { item }; } static void AddToCollection<T>(List<T> list, T item) { list.Add(item); } // ... var c = CreateCollection(new { a = 5, b = "foo" }); AddToCollection(c, new { a = 6, b = "bar" }); 

    If you need to save the collection somewhere, you can try to find the base type or write a generic adapter:

     ICollection Collection { get; set; } IEnumerable<object> AnotherCollection { get; set; } // ... Collection = CreateCollection(new { a = 5, b = "foo" }); AnotherCollection = CreateCollection(new { a = 6, b = "bar" }); 

    Also, you can always use the "heavy artillery" - dynamic (but it will slow down, I warned).

    But if there are too many problems with anonymous classes - perhaps you should already move on to the regular class?

    • If there is already a collection, then according to the idea AddToCollection is not needed? - VladD
    • @VladD, yeah, it turns out that, by the way, in the example of creating a collection, it will immediately have an element, that is, you cannot create an empty collection in this way - Grundy
    • @Grundy with an element template - can be - Pavel Mayorov
    • @PavelMayorov, I meant in a specific example in the answer. you always insert an item that was transferred to the list - Grundy
    • @Grundy Well, so I described the principle, not a solution - Pavel Mayorov

    An alternative way to create a list without using the generic method:

     var collection = Enumerable.Range(0, 0) .Select(a => new { a = default(int), b = default(string) }) .ToList(); collection.Add(new { a = 5, b = "foo" }); 

    In this case, Enumerable.Range is used, which returns an empty collection, but the type of the elements is determined by the select. When applying ToList get a regular list with the type of the elements of the anonymous class.

    • Well, I would not say that without the Generic method. Yet Select and ToList very even Generic. - Vadim Ovchinnikov
    • @VadimOvchinnikov, I meant my own, as in the example of Paul, in which only the List constructor is called, with the necessary generic parameter - Grundy

    Suppose there is an item variable:

     var item = new { Value = 1, Text = "abc" }; 

    First way

    You can make an array of it

     var items = new[] { item }; 

    In the same way you can make an array of several variables. Of course, it can be turned into a list using the ToList() method.

    Second way

    You can simply use the Enumerable.Repeat method

     var items = Enumerable.Repeat(item, 1); 

    If it is necessary to duplicate this element several times, then we transfer to this method not 1 , but the necessary number of times. Then add a call to ToList or ToArray to taste.

    Third way

    The idea is submitted by @Grundy, but I would clarify that it is not necessary to call Select exactly for the sequence of numbers obtained from the Enumerable.Range method.

    Take any suitable collection and call the Select method. If you also need an index, remember to overload Select with an index . And in general, use this method when the first and second is not so convenient to use otherwise it will look artificial. Example:

     var strings = new[] { "abc", "def" }; // [ "{ Value = 1, Text = "abc" }, { Value = 2, Text = "def" } ] var items = strings.Select((value, index) => new { Value = index + 1, Text = value }).ToArray(); 

    Adding items after initialization

    Then (if necessary) you can add elements either through the Add method of the list ( List class) or via the LINQ method Concat (a bit perverse, but also possible).

     items = items.Concat(new[] { new { Value = 2, Text = "def" } }).ToArray(); 
    • Notice that my code creates an empty sequence and Select is needed only to specify the type of elements - Grundy
    • @Grundy Yes, I noticed it. Just if it is read literally or simply it will be the first answer, then it will look weird for that reason. - Vadim Ovchinnikov