9

我有两个问题:

问题 1 背景: 在查看 Microsoft 的 LINQ 中“AsEnumerable()”方法的实现时,我注意到:

public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{ 
   return source;
} 

问题 1: 我在这里期待某种类型的转换或其他东西,但它只是返回它传递的值。这是如何运作的 ?

问题 2/3 背景: 我一直在尝试理解协方差、逆变和不变量。我想,我有一个模糊的理解,即在将子类型分配给父类型时,'in' 和 'out' 关键字决定了多态行为。

问题2: 我从阅读中知道 IEnumerable 是协变的,而 List 是不变的,那么为什么这是不可能的:

List<char> content = "testString".AsEnumerable();

问题 3:
如果 IList 实现 IEnumerable 那么为什么这是不可能的:

IEnumerable<char> content1 = "testString";
IList<char> content2 = content1;

请帮助我理解,提前谢谢。

4

1 回答 1

3
  1. 输入参数已知具有类型IEnumerable<TSource>。为什么它需要投射任何东西?将对象强制转换为该类型TSource不会产生任何影响,因为它们已经被保证为该类型(或更多派生类型)。

  2. 您不能将 type 的值分配给 typeIEnumerable<char>的变量List<char>。我认为您在这里的想法是相反的;List<char>源自IEnumerable<char>,而不是相反。List<T>这与不变性无关。IEnumerable<T>是协变的(更准确地说,类型参数T是协变的),这给了我们这种情况:

    IEnumerable enumerable = Enumerable.Empty<string>(); // Allowed
    IEnumerable<string> genericEnumerable = enumerable; // Not allowed
    
  3. 同样,IList<char>继承自IEnumerable<char>,而不是相反。你可以这样做:

    IList<char> content1 = "testString".ToList();
    IEnumerable<char> content2 = content1;
    

    恐怕你所要求的没有意义,而且与协方差无关。协变的事实IEnumerable<T>意味着您可以这样做:

    IEnumerable<object> asObject = new List<string>() { "test" };
    

    但是List<T>是不变的,所以你不能这样做:

    List<object> asObject = new List<string>() { "test" };
    
于 2013-07-31T14:12:37.757 回答