簡體   English   中英

具有多個參數的Func方差

[英]Func variance with multiple parameters

在我們的代碼中嘗試了類似的東西,但它失敗了:

Func<Employee, Employee> _myFunc;

void Main()
{
    Func<Employee, Employee> test1  = _myFunc;//Ok
    Func<Employee, Person> test2  = _myFunc;//Ok
    Func<Person, Employee> test3 = _myFunc;//Fails
    Func<Person, Person> test4  = _myFunc;//Fails
}

public class Person { }
public class Employee : Person { }

最后兩個案例給出了這個錯誤:

無法將System.Func<Employee, Employee>類型隱式轉換為System.Func<Person, Employee> 存在顯式轉換(您是否錯過了演員?)

知道為什么嗎?

如果你看一下Func<T, TResult>的簽名,你會看到輸入參數(在這種情況下為T )是逆變的 ,返回類型( TResult )是協變的

public delegate TResult Func<in T, out TResult>(T arg);

逆變量基本上是關於能夠將“更大”類型傳遞給期望“更小”類型的方法,其中協方差恰恰相反。

埃里克·利珀特 Eric Lippert )非常優雅(強調我的)

如果具有引用類型參數的構造保留賦值兼容性的方向,則泛型類型I是協變的 (在T中)。 如果它顛倒了賦值兼容性的方向,則它是逆變的 (在T中)。 如果兩者都沒有 ,那就是不變的 通過這種方式,我們只是簡單地說,采用T並產生I的投影是協變/逆變/不變投影。

因為Func<T, TResult>被定義為

public delegate TResult Func<in T, out TResult>(T arg);

正如你所看到的,第二個參數( TResult )確實是一個協變,但第一個參數( T ,它是函數的輸入)實際上是一個逆變(你只能用不太衍生的東西來提供它)。

Func<Employee, Person>很好,因為它與簽名匹配,而Func<Person, Person>失敗,因為它不是。

請參閱MSDN

好的,我想我現在明白了:

void Main()
{
    Func<Employee, Employee> getEmployeesBoss = (Employee employee) => {return employee.Boss;};
    //This works as it expects a Person to be returned and employee.Boss is a person.
    Func<Employee, Person> getEmployeesBoss1 = getEmployeesBoss;
    //This fails as I could pass a non Employee person to this func which would not work.
    Func<Person, Employee> getEmployeesBoss2 = getEmployeesBoss;
}

class Person {} 
class Employee : Person { public Employee Boss{get;set;}    }

一個Person不是Employee

Func<Employee, xxx>Func<Person, xxx>之間沒有可能的Func<Employee, xxx>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM