Arasındaki fark nedir <out T>ve <T>? Örneğin:
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
Arasındaki fark nedir <out T>ve <T>? Örneğin:
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
Yanıtlar:
outJenerik anahtar arayüzü tipi T-bildirdiğinden olduğunu belirtmek için kullanılır. Ayrıntılar için Kovaryans ve karşıtlık konusuna bakın .
Klasik örnek IEnumerable<out T>. Yana IEnumerable<out T>bildirdiğinden olduğunu aşağıdakileri yapmanız izin konum:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
Yukarıdaki ikinci satır, eğer kovaryant değilse, mantıksal olarak çalışsa da, dize nesneden türediğinden başarısız olur. C # ve VB.NET'e (VS 2010 ile .NET 4'te) genel arabirimlerdeki varyans eklenmeden önce , bu bir derleme zamanı hatasıydı.
.NET 4'ten sonra IEnumerable<T>kovaryant olarak işaretlendi ve oldu IEnumerable<out T>. Yana IEnumerable<out T>sadece içindeki unsurları kullanır ve asla ekler / o 's gelir nesnelerinin numaralandırılabilir koleksiyonu, stringler enumerable koleksiyon tedavi etmek artık güvenli, onları değiştirir covariant .
Bir yöntemi IList<T>olduğundan, bu tür bir tür ile çalışmaz . Buna izin verileceğini varsayalım:IList<T>Add
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
Daha sonra şunu arayabilirsiniz:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
Bu elbette başarısız olur - bu nedenle IList<T>kovaryant olarak işaretlenemez.
Ayrıca, inkarşılaştırma arabirimleri gibi şeyler tarafından kullanılan - btw, için bir seçenek vardır . IComparer<in T>, örneğin, tam tersi şekilde çalışır. Bir beton kullanabilirsiniz IComparer<Foo>bir şekilde doğrudan IComparer<Bar>eğer Barbir alt sınıfıdır Foo, çünkü IComparer<in T>arayüz kontravaryant .
Imagesoyut bir sınıf;) new List<object>() { Image.FromFile("test.jpg") };Hiçbir sorun olmadan yapabilirsiniz, ya da yapabilirsiniz new List<object>() { new Bitmap("test.jpg") };. Sizinki ile ilgili sorun new Image()izin verilmiyor (her var img = new Image();ikisini de yapamazsınız )
IList<object>tuhaf bir örnektir, eğer isterseniz objectjeneriklere ihtiyacınız yoktur.
inVe outanahtar kelimelerinin (aynı zamanda kovaryans ve kontravaryans) kullanımını kolayca hatırlamak için , kalıtımı sarma olarak görüntüleyebiliriz:
String : Object
Bar : Foo

düşünmek,
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
ve fonksiyonlar,
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
Kabul işlevi ICovariantSkinned<Fruit>kabul etmek mümkün olacak ICovariantSkinned<Fruit>ya da ICovariantSkinned<Bananna>çünkü ICovariantSkinned<T>bir kovaryant arayüzüdür ve BananatürüdürFruit ,
kabul eden fonksiyon ISkinned<Fruit>sadece kabul edebilecektir ISkinned<Fruit>.
" out T", bu türün T"kovaryant" olduğunu belirtir . Bu T, genel sınıf, arabirim veya yöntemin yöntemlerinde yalnızca döndürülen (giden) bir değer olarak görünmeyi kısıtlar . Bunun anlamı, type / interface / yöntemini, süper türdeki bir eşdeğere yayınlayabilmenizdir T.
Örneğin ICovariant<out Dog>için dökme olabilir ICovariant<Animal>.
outokuyana Tkadar sadece geri verilebilecek zorlamaların farkında değildim. Bütün konsept şimdi daha anlamlı!
Gönderdiğiniz bağlantıdan ....
Genel tür parametreleri için, out anahtar sözcüğü type parametresinin kovaryant olduğunu belirtir .
EDIT : Yine, gönderdiğiniz bağlantıdan
Daha fazla bilgi için, bkz. Kovaryans ve Çelişki (C # ve Visual Basic). http://msdn.microsoft.com/en-us/library/ee207183.aspx