Aracılığıyla paylaş


Genel Arabirimlerde Varyans (C#)

.NET Framework 4, çeşitli mevcut genel arabirimler için varyans desteği sunar. Varyans desteği, bu arabirimleri uygulayan sınıfların örtük olarak dönüştürülmesi sağlar.

.NET Framework 4'den başlayarak, aşağıdaki arabirimler değişkendir:

.NET Framework 4.5'den başlayarak, aşağıdaki arabirimler değişkendir:

Kovaryans, bir yöntemin arabirimin genel tür parametresi tarafından tanımlanandan daha türetilmiş bir dönüş türüne sahip olmasına izin verir. Kovaryans özelliğini göstermek için şu genel arabirimleri göz önünde bulundurun: IEnumerable<Object> ve IEnumerable<String>. IEnumerable<String> arabirimi, IEnumerable<Object> arabirimini devralmıyor. Ancak, String türü, Object türünü devralır ve bazı durumlarda bu arabirimlerin nesnelerini birbirine atamak isteyebilirsiniz. Bu, aşağıdaki kod örneğinde gösterilmiştir.

IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;

.NET Framework'ün önceki sürümlerinde, bu kod C# ve açıksa Option Strict Visual Basic'te bir derleme hatasına neden olur. Artık, önceki örnekte gösterildiği gibi, strings arabirimi birlikte değişken olduğu için objects yerine IEnumerable<T> kullanabilirsiniz.

Contravariance, bir yöntemin arabiriminin genel parametresi tarafından belirtilenden daha az türetilmiş bağımsız değişken türlerine sahip olmasına izin verir. Kontravaryansı göstermek için, BaseComparer sınıfının örneklerini karşılaştırmak amacıyla bir BaseClass sınıfı oluşturduğunuzu varsayalım. BaseComparer sınıfı, IEqualityComparer<BaseClass> arabirimini uygular. IEqualityComparer<T> Arabirim artık değişkensiz olduğundan, sınıfı devralan BaseComparer sınıfların örneklerini karşılaştırmak için kullanabilirsinizBaseClass. Bu, aşağıdaki kod örneğinde gösterilmiştir.

// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }

// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass>
{
    public int GetHashCode(BaseClass baseInstance)
    {
        return baseInstance.GetHashCode();
    }
    public bool Equals(BaseClass x, BaseClass y)
    {
        return x == y;
    }
}
class Program
{
    static void Test()
    {
        IEqualityComparer<BaseClass> baseComparer = new BaseComparer();

        // Implicit conversion of IEqualityComparer<BaseClass> to
        // IEqualityComparer<DerivedClass>.
        IEqualityComparer<DerivedClass> childComparer = baseComparer;
    }
}

Daha fazla örnek için bkz. Genel Koleksiyonlar için Arabirimlerde Varyans Kullanma (C#).

Genel arabirimlerdeki varyans yalnızca başvuru türleri için desteklenir. Değer türleri varyansı desteklemez. Örneğin, IEnumerable<int> öğesi, tamsayılar bir değer türüyle temsil edildiğinden IEnumerable<object> öğesine örtük olarak dönüştürülemez.

IEnumerable<int> integers = new List<int>();
// The following statement generates a compiler error,
// because int is a value type.
// IEnumerable<Object> objects = integers;

Değişken arabirimleri uygulayan sınıfların hala sabit olduğunu unutmamak da önemlidir. Örneğin, List<T> değişken ara birimini IEnumerable<T> uygulasa da, List<String>'yi List<Object>'ye örtük olarak dönüştüremezsiniz. Bu, aşağıdaki kod örneğinde gösterilmiştir.

// The following line generates a compiler error
// because classes are invariant.
// List<Object> list = new List<String>();

// You can use the interface object instead.
IEnumerable<Object> listObjects = new List<String>();

Ayrıca bakınız