2010年12月9日 星期四

Generics Variance

一個有趣的問題。以下的程式可以編譯嗎?

using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            List<A> listA = new List<A>();
            List<B> listB = new List<B>();
            listA.AddRange(listB.AsEnumerable());
        }
    }

    internal class A{} 
    class B : A{}
}
答案很好玩,.NET Framwork 4可以,.NET 2.0 不可以。
.NET Framwork 2 的錯誤訊息是

cannot convert from 'System.Collections.Generic.IEnumerable<B>' to 'System.Collections.Generic.IEnumerable<A>'   

這是為什麼呢?B 是 A 的子代,把 B 當成A 加到 listA 這個集合中,看起來沒有什麼不對。

原因是 .NET Framwork 2 的泛型(Generics)尚不支援這樣的場景。這樣的狀況稱 Generics Variance。以前的處理方式請參考Variance in Generic Types

當然,這樣的問題已經在 .NET Framework 4 中得到了解決。

 

沒有留言:

Share with Facebook