2014年5月10日 星期六

委拖(delegate)的協變與逆變

建立一個介面和一個實現介面的類別
internal interface IVehicle
{
    string Name { getset; }
}
 
internal class Car : IVehicle
{
    public string Name { getset; }
 
    public int Doors { getset; }
}

使用熟悉的類型進行演示
delegate T Func<out T>
delegate void Action<in T>(T obj)

使用 Lambda表達式可以很輕易地進行演示,甚至可以將他們連接起來
Func<Car> carFactory = () => new Car { Name = "BMW", Doors = 4 };
Func<IVehicle> vehicleFactory = carFactory; // 使用協變性轉換 Func<T>
 
Action<IVehicle> vehicleShow = vehicle => Console.WriteLine(vehicle.Name);
Action<Car> CarShow = vehicleShow; // 使用逆變性轉換 Action<T>
 
// 完整檢查
CarShow(carFactory()); // BMW
vehicleShow(vehicleFactory()); // BMW

協變性允許我們將汽車工廠視為更一般的載具(交通工具)工廠。
創建一個通用的行為,打印任何載具的名稱,使用逆變轉換,讓行為可用於人和載具。
最後將汽車工廠的結果提供給汽車展行為(action),將載具工廠的結果給載具秀行為,結果都是BMW

查看 vehicleFactor() 執行的結果
Console.WriteLine(vehicleFactory().Name);
Console.WriteLine(((Car)vehicleFactory()).Doors);
第一行顯示 BMW
第二行必須轉換類行為 Car 才能查看 Doors 屬性

沒有留言: