我看到的在下面的用法:參數列表中的修飾符的含義是什麼?
Covariance and contravariance real world example
interface IGobbler<in T> {
void gobble(T t);
}
我不明白的在代表使用。是否與編號,出?
我看到的在下面的用法:參數列表中的修飾符的含義是什麼?
Covariance and contravariance real world example
interface IGobbler<in T> {
void gobble(T t);
}
我不明白的在代表使用。是否與編號,出?
忽略你對ref
和out
的瞭解,因爲它與此上下文無關。在這種情況下,in
意味着T
只會出現在函數名稱的右側(即在形式參數列表中,如void gobble(T t)
)。如果它說out
,那麼T
只會出現在函數名的左側(即返回值如T foo(int x)
)。默認(不指定任何內容)允許T
出現在任何地方。
4.0中的in
和out
修飾符對強制執行(或者說:啓用)協方差和逆變是必需的。
如果添加in
,您只能在向內(逆變)位置使用T
- 所以像Add(T obj)
是好的,但T this[int index] {get;}
不因爲這是一個向外(協)的位置。
這對於4.0中的方差特徵很重要。有差異的話,ref
和out
都不可用(它們都是,都是這樣:都不)。
您的進出口說明很容易理解。但我仍然無法連接T和接口IGobbler
@ q0987不,這是不正確的;代表***或接口***。最值得注意的是,它現在是'IEnumerable
在'IGobbler
在C#4.0,逆變允許 例如,的IComparer
<X>
待鑄造到 的IComparer<Y>
即使Y是衍生 類型X的要做到這一點的IComparer 應標明與在改性劑。
public interface IComparer<in T> {
public int Compare(T left, T right);
}
有無看看這裏的舉例和說明:
http://www.csharphelp.com/2010/02/c-4-0-covariance-and-contravariance-of-generics/
的in
修飾符告訴你的類型是逆變並可以隱式轉換爲窄型。在下面的例子中注意到,儘管狼吞虎嚥需要Shape
,但它可以被分配到Action<Rectangle>
,因爲我們已經聲明它是逆變的。這是因爲任何調用委託並將其傳遞給Rectangle的人都可以將Rectangle傳遞給一個也需要Shape的方法。
當您使用in
和out
時,有一些規則,但是這就是它簡單介紹的內容。
例如:
public class Shape { }
public class Rectangle : Shape { }
public interface IGobbler<Shape>
{
void gobble(Shape shape);
}
public class Gobbler : IGobbler<Shape>
{
public void gobble(Shape r) { }
}
public static class Program
{
public static void Main()
{
var g = new Gobbler();
// notice can implictly convert to a narrower type because of the 'in' keyword
Action<Rectangle> r = g.gobble;
}
}
IN關鍵字告訴我們只希望使用T作爲輸入值的編譯器。
它不會允許來自比方說,IGobbler鑄造IGobbler
我喜歡把它看作是消費和生產,因爲這些對於大多數開發人員熟悉的隱喻。需要IGobbler<Cow>
的方法也可以接受IGobbler<Animal>
,因爲可以吞噬(消耗)任何動物的狼吞虎嚥也可以吞噬牛。這裏的Gobbler是一種特定類型動物的消費者,所以它使用in
標籤。
上述案例(反變換)看起來可能與直覺相反,但從RestaurantOwner的角度考慮,他想要一個Gobbler<Cow>
。如果一個戈布勒爾只會吞噬豬,並且該餐廳的所有者試圖給他喂牛,那麼它就行不通。他只能接受不那麼挑剔的戈布勒,所以Gobbler<Animal>
或Gobbler<Herbivore>
工作正常。
在另一方面,假設你有一個Farmer<Animal>
出售的動物(具有返回IEnumerable<Animal>
一個農場方法。)如果你有想要Buy(IEnumerable<Animal>)
一個買方,那麼它可以接受Farmer<Cow>.Farm()
,作爲買方願意購買任何生產的動物和母牛都是動物。這裏的農民是特定類型動物的生產者,所以它使用'out'標籤。
進出與參考和輸出沒有任何關係。
in關鍵字被用於描述在該接口的實例將消耗T的一個實例在該實例中,你鏈接的線
創建火雞,可以餵驢到沉綿的驢不是一個QuadrupledCreature,但它來自它。所以你可以使用更專門的實例而不是基類作爲參數。
out關鍵字的工作方式大致相同,只是它用於描述產生東西而不是包含它的東西。
在同一示例中,線
ISpewer<Rodent> rs = new MouseSpewer();
創建ISpewer,其調用時噴出鼠標。鼠標不是齧齒動物,而是從中派生出來的,因此您可以使用生成的類生成比接口聲明的更專用的實例。
請注意在兩種情況下,最特殊的類是如何交換的。當使用in關鍵字時,你使用專用類作爲接口的通用參數,而在這種情況下,你使用基類作爲通用參數來告訴編譯器,儘管你創建了一個更專門的類,它應該把它當作基類來對待。
這個聲明是如何工作的? IGobbler
QuadrupedGobbler實現通用的IGobbler接口,該接口通過協方差特別是接口的簽名,看起來像這樣'public interface IGobbler
您是否搜索過?如果搜索引擎不採用「in」這個詞,你可能需要使用'+ in'而不是'in'。 – BoltClock 2011-06-01 15:28:26
ref在這方面不適用 – Jodrell 2011-06-01 15:28:41
@BoltClock,我通過使用'C#parameter ref in'或'C#in parameter'搜索谷歌並且沒有有用的信息被返回。 – q0987 2011-06-01 15:42:00