1. 程式人生 > >【轉】編寫高質量代碼改善C#程序的157個建議——建議44:理解委托中的協變

【轉】編寫高質量代碼改善C#程序的157個建議——建議44:理解委托中的協變

關鍵字 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:理解委托中的協變