【轉】編寫高質量代碼改善C#程序的157個建議——建議44:理解委托中的協變
阿新 • • 發佈:2017-12-05
關鍵字 man 常常 manage count () leg temp res
建議44:理解委托中的協變
委托中的泛型變量天然是部分支持協變的。為什麽是“部分支持協變”?看下面示例:
class Program { public delegate T GetEmployeeHanlder<T>(string name); static void Main() { GetEmployeeHanlder<Employee> getAEmployee = GetAManager; Employee e = getAEmployee("Mike"); } static Manager GetAManager(string name) { Console.WriteLine("我是經理: " + name); return new Manager() { Name = name }; } static Employee GetAEmployee(string name) { Console.WriteLine("我是雇員: " + name);return new Employee() { Name = name }; } } interface ISalary<T> { void Pay(); } class BaseSalaryCounter<T> : ISalary<T> { public void Pay() { Console.WriteLine("Pay base salary"); } } class Employee {public string Name { get; set; } } class Programmer : Employee { } class Manager : Employee { }
上中的GetAManager返回的是一個Manager,但是在使用中,其實是將其賦值給一個泛型參數為Employee的委托變量。因為存在下面一種情況,所以編譯不過:
GetEmployeeHanlder<Manager> getAManager = GetAManager;
GetEmployeeHanlder<Employee> getAEmployee = GetAManager;
要讓上面的代碼編譯通過,同樣需要為委托中的泛型參數指定out關鍵字:
public delegate T GetEmployeeHanlder<out T>(string name);
除非考慮到該委托聲明肯定不會用於可變性,否則,為委托中的泛型參數指定out關鍵字將會拓展委托的應用,建議在實際編碼過程中永遠這樣使用。實際上,FCL4.0中的一些委托聲明已經用out關鍵字來讓委托支持協變了,如我們常常會使用到的:
public delegate TResult Func<out TResult>(); public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技
【轉】編寫高質量代碼改善C#程序的157個建議——建議44:理解委托中的協變