为什么IEnumerable的匿名类型不会在ToList()上返回List <object>?

时间:2018-02-15 16:54:30

标签: c# anonymous-types

这是我想要创建的简化函数:

static List<object> GetAnonList(IEnumerable<string> names)
{
    return names.Select(name => new { FirstName = name }).ToList();
}

在该代码块中,我收到编译器错误:

  

错误CS0029无法隐式转换类型   'System.Collections.Generic.List&LT;&GT;'   到'System.Collections.Generic.List'

在匿名类型的documentation中,它表示匿名类型被视为类型对象。为什么C#编译器不会在List<object>上返回names.ToList()

此外,为什么以下代码不会导致错误?如果无法将List<<anonymous type: string FirstName>>转换为List<object>,那么为什么可以将其转换为IEnumberable<object>

static IEnumerable<object> GetAnonList(IEnumerable<string> names)
{
    return names.Select(name => new { FirstName = name }).ToList();
}

2 个答案:

答案 0 :(得分:8)

  

如果无法将List<<anonymous type: string FirstName>>转换为List<object>,那么为什么可以将其转换为IEnumberable<object>

那是因为IEnumerable<T>是协变的而List<T>不是。它与匿名类型无关。

如果你编写的代码是工作的,那么你就可以使用List<string>作为List<object>并添加任何内容来打破类型安全。

您可以通过将通用类型参数传递给ToList调用来使代码工作:

static List<object> GetAnonList(IEnumerable<string> names)
{
    return names.Select(name => new { FirstName = name }).ToList<object>();
}

但是除了这种方法之外,你几乎无法做到这一点。除非您使用反射,否则您将无法访问FirstName属性。

答案 1 :(得分:0)

List<T> IEnumerable(T) Document

{{1}} List(T) Document

请注意,有&#34; out&#34; IEnumerable接口上的泛型修饰符,允许您将更多派生类型放入IEnumerable。

请参阅out (Generic Modifier) (C# Reference)