2013-07-12 56 views
1

我有幾個地方我都使用Action<Int32>Action<Boolean>Action<SomeClassName>,但是當涉及到傳遞行動的一類方法的參數,我不能投Action<Int32>Action<Boolean>Action<Object>爲什麼我不能動作<Int32>動作<Object>?

爲什麼不能用簡單的類型轉換進行轉換?這個演員是可能的嗎?最後,如果可能的話,我將如何去做這個演員陣容。

回答

10

因爲它會破壞類型安全。

當您聲明Action<Int32>時,您說「這是需要一個Int32參數的代表」。

如果這可以直接轉換爲Action<object>,那麼您現在可以使用肯定不是Int32的行爲來調用動作,例如DateTime。在這種情況下,C#可以防止你在腳下拍攝自己。

3

你不能讓經協方差直接投(或者是逆變?),因爲Action<int>根本不一個Action<object> - 後者可以傳遞任何對象,而前者可以只通過了int

可以圍繞此包裹你的動作,這樣的:

Action<int> aInt = ...; 
Action<object> aObj = o => aInt((int)o); 

這再次表明你爲什麼投可能不是一個好主意 - 如果你通過aObj任何東西,除了一個int,你會得到一個演員例外。

相反,你可以理論上只投一個Action<object>Action<int>,因爲如果你可以通過它任何對象,可以肯定它的int。但是,實際上這隻適用於參考類型,而不適用於值類型 - 因此您可以使用string,但不適用於int

+1

這將是協變性,但'行動'在T中是逆變的。它是協變性,如果「可轉換性箭頭」朝相同的方向。如果'string - > object'暗示'X - > X '那麼'X '是協變的,因爲箭頭相互對應。如果'string - > object'意味着'X <-- X'那麼箭頭是相反的方向,所以它是逆變的。 –

+0

...就這樣,'co'和'contra'現在對我有意義。謝謝埃裏克! – Rawling

1

在輸入爲Int32的限制下進行操作。這意味着您使用的操作可以對輸入作爲int進行假設。例如,你可以用另一個int n => Console.WriteLine(n + 4)做數學運算。所以這個動作或功能很適合那個盒子。如果你改變方框,以前做出的假設仍然必須保持。你基本上有一個反向關係,或逆變,到「常規」鑄造方案,例如:object a = (object) 2;

只要記住任何符合操作框的東西都不會對其輸入行爲做任何假設。功能n => Console.WriteLine(n)緊貼在裏面,因爲所有的對象都可以被打印。並非所有對象都可以像整數一樣操作。

相關問題