2

This code:

var items = query.ToList();

returns List<'a> where 'a is new { string a1, string a2 }

If I were to remove the var keyword, what would be a valid type definition to use here that keeps the names a1 and a2?

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
Nicholas
  • 1,392
  • 16
  • 38
  • 1
    You cannot determine an anonymous type at compile time. That's a main reason `var` was added. You can replace the anonymous type with `Tuple` or a custom class though. – juharr Sep 05 '17 at 13:41
  • @juharr I think it would be safer to say that `var` exists only for types that *can* be determined at compile time (try using it with one that can't). IIRC it predates anonymous types by a version or two. – 15ee8f99-57ff-4f92-890c-b56153 Sep 05 '17 at 13:42
  • @EdPlunkett Yeah, my wording should be before compile time. – juharr Sep 05 '17 at 13:43

4 Answers4

10

Nothing, because it's a list of an anonymous type. The very term "anonymous type" was chosen because the type doesn't have a name.

If you want to be able to use explicit typing, don't use an anonymous type. Either create your own type, or (in C# 7) use a C# tuple type. (The regular System.Tuple type wouldn't let you preserve the names you want.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Realistically I just wanted an easy way to make it a class variable instead of a local variable. I could reprocess it with a loop into a different structure, I just thought there might be a simplistic method. – Nicholas Sep 05 '17 at 13:59
  • @Nicholas - no need to reprocess it. Perhaps update question with query – Gilad Green Sep 05 '17 at 14:00
  • 1
    @Nicholas: No, you simply can't declare variables that use anonymous types as type arguments. – Jon Skeet Sep 05 '17 at 14:11
3

Your query is returning an anonymous type and therefore you do not know the type name at compilation time. If you want to remove the var project to a custom type instead of an anonymous type.

If you are in need to remove the var and know the type then do not use anonymous types. Have a look at: Why use anonymous types instead of creating a class


To use something along the lines of your comment: List< { string a1, string a2 } > look into Named Tuples in C# 7.0. You have have a look under C# 7.0 new features or Better naming in Tuple classes than "Item1", "Item2"

Something along the following:

List(string a1, string a2) result = (from item from collection
                                    select new (string a1, string a2) 
                                        { "firstString", "secondString" }).ToList();
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
0

The point about anonymous types is that they are not available at design time (when writing the code). They will be provided somewhere hidden by the compiler when the code is compiled. They have a name, and they are properly designed, but the types are inaccessible at design time by design.

That’s why you are using var; to let the compiler figure out what type this actually is, since the compiler is the only instance here that can tell you “where” the type is.

If you could replace the var by something real at design time, then you could also replace the new { … } by new Whatever { … } which would make this type no longer anonymous. – So if you want to use a type instead of var there, define an actual type yourself. Remember that doing that does not actually have a difference to what the compiler does for you anyway; it’s just you now who is writing that class declaration.

poke
  • 369,085
  • 72
  • 557
  • 602
0

The only possible way is to downcast the result to non-anonymous ancestors of List<'a> type - IList or IEnumerable:

IList items = query.ToList();
stop-cran
  • 4,229
  • 2
  • 30
  • 47