我有兩個商務合同類:行動代表,泛型,協方差和逆變
public BusinessContract
public Person : BusinessContract
在另一大類,我有以下代碼:
private Action<BusinessContract> _foo;
public void Foo<T>(Action<T> bar) where T : BusinessContract
{
_foo = bar;
}
上面甚至不會編譯,這讓我有些困惑。我將T約束爲BusinessContract,爲什麼編譯器不知道bar可以分配給_foo?
在試圖解決這個問題,我們試圖將其更改爲以下:
public void Foo<T>(Action<T> bar) where T : BusinessContract
{
_foo = (Action<BusinessContract>)bar;
}
現在,編譯器是幸福的,所以我在其他地方寫下面的代碼在我的應用程序:
Foo<Person>(p => p.Name = "Joe");
運行時應用程序爆發InvalidCastException。
我不明白。我應該不能將更具體的類型轉換爲不太特定的類型並分配它?
UPDATE
喬恩回答了這個問題,從而得到了該點頭,只是收在這個循環中,這裏是我們如何最終解決問題。
private Action<BusinessContract> _foo;
public void Foo<T>(Action<T> bar) where T : BusinessContract
{
_foo = contract => bar((T)contract);
}
我們爲什麼要這樣做?我們有一個假的DAL,我們用於單元測試。使用其中一種方法,我們需要給測試開發人員指定在測試過程中調用方法時應該執行的操作(它是從數據庫更新緩存對象的刷新方法)。 Foo的目的是設置在刷新被調用時應該發生的事情。 IOW,在這個課程的其他地方,我們有以下內容。
public void Refresh(BusinessContract contract)
{
if(_foo != null)
{
_foo(contract);
}
}
例如,測試開發人員可以決定當調用Refresh時他們想要將名稱設置爲不同的值。
Foo<Person>(p => p.Name = "New Name");
@MDeSchaepmeester:不,我不是 - 在工作代碼中(後半部分),我將一個'Action
你是對的,愚蠢的錯誤,我沒有真正讀過這段代碼,並假定你用_foo作爲參數調用Foo(我來這裏是因爲我在做* *) – MarioDS