1

I would like to know the reason that does not allow this type of convertion. The subject was already approached in this post in SO, but I want the low level explanation on why this is not possible natively.

Why does these casts fail?

OBS: I know it is possible to do so by reflection.

IList<People> peopleList = new List<People>()
{
    new People() { Name = "Again", Age = 10 },
    new People() { Name = "Over", Age = 20 },
    new People() { Name = "Jonh", Age = 30 },
    new People() { Name = "Enzo", Age = 40 },
};

var anonymous = (from p in peopleList
                select new
                {
                    Name = p.Name,
                    Age = p.Age
                });

// Does not work
IList<People> listt = (IList<People>)anonymous; 
//Does not Work
IList<People> listt = (anonymous as List<People>);
12
  • 8
    I guess it would be interesting why you think it should work. An anonymous type is not another type, even if it has the same fields. The same goes for any other type, anonymous or not. That's how the language was built, there is no duck-typing in C#. Commented Dec 15, 2017 at 13:40
  • 1
    Why should it work? It's an anonymous type, not a People instance. There's no conceivable cast from one to another. Cast means "treat this object as if it were that other equivalent type". There's nothing that says this anonymous type is equivalent to People. What if you used it to represent pets? Commented Dec 15, 2017 at 13:40
  • your anonymous type is not People and there is no conversion between these two types. Why should that cast work? How should the compiler know how to convert People to your anonymous type? And even if it does, a IList<sometype> still is a totally different type than IList<People>. Commented Dec 15, 2017 at 13:41
  • The "low level" reason it doesn't work, is because it isn't defined as a supported cast in the C# language spec. Commented Dec 15, 2017 at 13:44
  • 3
    This is called "Duck Typing" BTW. If it walks like a duck, and quacks like a duck, treat it like a duck. It isn't available in C# as a first-class language feature, other than a few very specific cases. Commented Dec 15, 2017 at 13:46

1 Answer 1

5

The question is why anonymous cannot be successfully cast to IList<People> or List<People>.

  • The value of the query expression is an object that can execute the query. It is not the result set of a query execution. anonymous implements IEnumerable<T>, not IList<T> and certainly it does not subtype List<T>. So it cannot be cast to any IList<T> or List<T> type. If that's what you want then use ToList() to execute the query and store the result set in a list.
  • Can the query be cast to IEnumerable<People>? No. It is a sequence of anonymously-typed objects that have copied some of the values associated with a People. So it is a sequence of anonymous objects, not a sequence of people.

I note also that in new C# 7 code it's a better practice to use tuples instead of anonymous types if you can in your application. They have better support in the type system and produce less collection pressure.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.