Aracılığıyla paylaş


Variant Generic arabirimlerden (C# ve Visual Basic) oluşturma

Genel tür parametrelerinde arabirimleri değişkenle birlikte olarak bildirebilirsiniz veya değişken karşıtı.Kovaryans bir daha dönüş türleri genel tür parametreleri tarafından tanımlanan'den türetilen arabirim yöntemleri sağlar.Contravariance genel parametreleri tarafından belirtilenden daha az türetilmiş bağımsız değişken türleri arabirim yöntemleri sağlar.Değişkenle birlikte olan genel arabirimi veya değişken karşıtı genel türde parametreler olarak adlandırılan değişken.

[!NOT]

.net Framework 4 farkı birkaç varolan genel arabirim desteği sunar.Varyant Arabirimleri'nde listesi.net Framework Bkz: Varyans Generic arabirimlerden (C# ve Visual Basic).

Generic arabirimlerden değişken bildirme

Varyant genel arabirimleri kullanarak bildirebilirsiniz in ve out genel türde parametreler için anahtar sözcükler.

Önemli notÖnemli

ByRefVisual Basic'te parametreleri ve ref ve out C# [NULL]'taki parametreleri değişken olamaz.Değer türleri farkı da desteklemez.

Genel bir tür parametresiyle değişkenle birlikte kullanarak bildirebilirsiniz out anahtar sözcüğü.Değişkenle birlikte türü aşağıdaki koşulları karşılaması gerekir:

  • Tür arabirim yöntemleri dönüş türü yalnızca kullanılan ve bir tür yöntem bağımsız değişkenleri olarak kullanılmaz.Bu, aşağıdaki örnekte gösterilmiştir türü R değişkenle birlikte bildirilir.

    Interface ICovariant(Of Out R)
        Function GetSomething() As R
        ' The following statement generates a compiler error.
        ' Sub SetSomething(ByVal sampleArg As R)
    End Interface
    
    interface ICovariant<out R>
    {
        R GetSomething();
        // The following statement generates a compiler error.
        // void SetSometing(R sampleArg);
    
    }
    

    Bu kuralın tek istisnası yoktur.Karşıtı genel temsilci parametresi varsa, türü için temsilci genel tür parametre olarak kullanabilirsiniz.Bu türe göre gösterilmiştir R aşağıdaki örnekte.Daha fazla bilgi için, bkz. Varyans Temsilciler (C# ve Visual Basic) ve Farkı Func ve eylem genel Temsilciler için (C# ve Visual Basic) kullanma.

    Interface ICovariant(Of Out R)
        Sub DoSomething(ByVal callback As Action(Of R))
    End Interface
    
    interface ICovariant<out R>
    {
        void DoSomething(Action<R> callback);
    }
    
  • Tür arabirim yöntemleri için genel bir kısıtlama olarak kullanılmaz.Bu aşağıdaki kodda gösterilmiştir.

    Interface ICovariant(Of Out R)
        ' The following statement generates a compiler error
        ' because you can use only contravariant or invariant types
        ' in generic contstraints.
        ' Sub DoSomething(Of T As R)()
    End Interface
    
    interface ICovariant<out R>
    {
        // The following statement generates a compiler error
        // because you can use only contravariant or invariant types
        // in generic contstraints.
        // void DoSomething<T>() where T : R;
    }
    

Genel tür parametresi karşıtı kullanarak bildirebilirsiniz in anahtar sözcüğü.Arabirim yöntemleri dönüş türü değil de, yalnızca bir tür yöntem bağımsız değişkenleri olarak karşıtı türü kullanılabilir.Karşıtı türü genel sınırlamalar için de kullanılabilir.Aşağıdaki kod, karşıtı arabirim bildirmek ve genel bir sınırlama yöntemlerinden birini kullanın gösterilmiştir.

Interface IContravariant(Of In A)
    Sub SetSomething(ByVal sampleArg As A)
    Sub DoSomething(Of T As A)()
    ' The following statement generates a compiler error.
    ' Function GetSomething() As A
End Interface
interface IContravariant<in A>
{
    void SetSomething(A sampleArg);
    void DoSomething<T>() where T : A;
    // The following statement generates a compiler error.
    // A GetSomething();            
}

Ayrıca aşağıdaki kod örneğinde gösterildiği gibi hem Kovaryans hem de contravariance aynı arabirimi, ancak farklı türde parametreler için desteklemek mümkündür.

Interface IVariant(Of Out R, In A)
    Function GetSomething() As R
    Sub SetSomething(ByVal sampleArg As A)
    Function GetSetSomething(ByVal sampleArg As A) As R
End Interface
interface IVariant<out R, in A>
{
    R GetSomething();
    void SetSomething(A sampleArg);
    R GetSetSometings(A sampleArg);
}

Visual Basic'te, temsilci türü belirtmeden varyant Arabirimlerdeki olaylar bildirimini yapamazsınız.Ayrıca, bir değişken arabirimi sınıf, çeteleler ya da yapıları içe olamaz, ancak onu arabirimleri.Bu aşağıdaki kodda gösterilmiştir.

Interface ICovariant(Of Out R)
    ' The following statement generates a compiler error.
    ' Event SampleEvent()
    ' The following statement specifies the delegate type and 
    ' does not generate an error.
    Event AnotherEvent As EventHandler

    ' The following statements generate compiler errors,
    ' because a variant interface cannot have
    ' nested enums, classes, or structures.

    'Enum SampleEnum : test : End Enum
    'Class SampleClass : End Class
    'Structure SampleStructure : Dim value As Integer : End Structure

    ' Variant interfaces can have nested interfaces.
    Interface INested : End Interface
End Interface

Değişken genel arabirimleri uygulayan

Sınıflarda varyant generic arabirimlerden sabit arabirimleri için kullanılan aynı sözdizimini kullanarak uygular.Aşağıdaki kod örneği, genel bir sınıf içinde bir değişkenle birlikte arabirimini uygulayan gösterilmiştir.

Interface ICovariant(Of Out R)
    Function GetSomething() As R
End Interface

Class SampleImplementation(Of R)
    Implements ICovariant(Of R)
    Public Function GetSomething() As R _
    Implements ICovariant(Of R).GetSomething
        ' Some code.
    End Function
End Class
interface ICovariant<out R>
{
    R GetSomething();
}
class SampleImplementation<R> : ICovariant<R>
{
    public R GetSomething()
    {
        // Some code.
        return default(R);
    }
}

Varyant arabirimleri uygulayan sınıflar sabit.Örneğin, aşağıdaki kod düşünün.

' The interface is covariant.
Dim ibutton As ICovariant(Of Button) =
    New SampleImplementation(Of Button)
Dim iobj As ICovariant(Of Object) = ibutton

' The class is invariant.
Dim button As SampleImplementation(Of Button) =
    New SampleImplementation(Of Button)
' The following statement generates a compiler error
' because classes are invariant.
' Dim obj As SampleImplementation(Of Object) = button
// The interface is covariant.
ICovariant<Button> ibutton = new SampleImplementation<Button>();
ICovariant<Object> iobj = ibutton;

// The class is invariant.
SampleImplementation<Button> button = new SampleImplementation<Button>();
// The following statement generates a compiler error
// because classes are invariant.
// SampleImplementation<Object> obj = button;

Variant Generic arabirimlerden genişletme

Genel değişken bir arabirim genişlettiğinizde, kullanmak zorunda in ve out türetilen arabirimin farkı destekleyip desteklemediğini açıkça belirtmek için anahtar sözcükler.Derleyici sapması uzatılmış arabirimden gerçekleştirip değil.Örneğin, aşağıdaki arabirimlerden düşünün.

Interface ICovariant(Of Out T)
End Interface

Interface IInvariant(Of T)
    Inherits ICovariant(Of T)
End Interface

Interface IExtCovariant(Of Out T)
    Inherits ICovariant(Of T)
End Interface
interface ICovariant<out T> { }
interface IInvariant<T> : ICovariant<T> { }
interface IExtCovariant<out T> : ICovariant<T> { }

De IInvariant<T> (Invariant(Of T) Visual Basic) arabirim, genel tür parametresi T sabit, iş iken, IExtCovariant<out T> (IExtCovariant (Of Out T) Visual Basic) iki arabirim aynı arabirime yayýlabilir rağmen tür parametresi değişkenle birlikte,.Aynı kural karşıtı genel türde parametreler için uygulanır.

Genel parametre girildiği iki Arabirimi genişletiyor bir arabirim oluşturabilirsiniz T değişkenle birlikte olduğu ve genel tür parametresi, genişletme, karşıtı olduğu arabirimin arabirim T sabit olur.Bu, aşağıdaki kod örneğinde gösterilmiştir.

Interface ICovariant(Of Out T)
End Interface

Interface IContravariant(Of In T)
End Interface

Interface IInvariant(Of T)
    Inherits ICovariant(Of T), IContravariant(Of T)
End Interface
interface ICovariant<out T> { }
interface IContravariant<in T> { }
interface IInvariant<T> : ICovariant<T>, IContravariant<T> { }

Ancak, genel bir tür parametresiyle, T olduğu bir arabirimde değişkenle birlikte bildirilen, siz onu karşıtı bildiremezsiniz genişletme arabiriminde veya tam tersi.Bu, aşağıdaki kod örneğinde gösterilmiştir.

Interface ICovariant(Of Out T)
End Interface

' The following statements generate a compiler error.
' Interface ICoContraVariant(Of In T)
'     Inherits ICovariant(Of T)
' End Interface
interface ICovariant<out T> { }
// The following statement generates a compiler error.
// interface ICoContraVariant<in T> : ICovariant<T> { }

Dd997386.collapse_all(tr-tr,VS.110).gifBelirsizlik önleme

Farkı varyant Genel arabirim geliştirdiğinizde, belirsizlik için bazen yol açabilir.Bu kaçınılmalıdır.

Örneğin, bir sınıf, açıkça farklı genel tür parametrelerle aynı değişken genel arabirimini uygulayan, belirsizlik oluşturabilirsiniz.Derleyici bir hata bu durumda neden olmaz, ancak hangi arabirim geliþtirmesi zamanında seçilir belirtilmemiş.Bu ince hataların kodunuzda neden olabilir.Aþaðýdaki kod örneði ele alalým.

[!NOT]

İle Option Strict Off, Visual Basic, belirsiz arabirim geliþtirmesi olduğunda bir derleyici uyarı oluşturur.İle Option Strict On, Visual Basic derleyici hatası oluşturur.

' Simple class hierarchy.
Class Animal
End Class

Class Cat
    Inherits Animal
End Class

Class Dog
    Inherits Animal
End Class

' This class introduces ambiguity
' because IEnumerable(Of Out T) is covariant.
Class Pets
    Implements IEnumerable(Of Cat), IEnumerable(Of Dog)

    Public Function GetEnumerator() As IEnumerator(Of Cat) _
        Implements IEnumerable(Of Cat).GetEnumerator
        Console.WriteLine("Cat")
        ' Some code.
    End Function

    Public Function GetEnumerator1() As IEnumerator(Of Dog) _
        Implements IEnumerable(Of Dog).GetEnumerator
        Console.WriteLine("Dog")
        ' Some code.
    End Function

    Public Function GetEnumerator2() As IEnumerator _
        Implements IEnumerable.GetEnumerator
        ' Some code.
    End Function
End Class

Sub Main()
    Dim pets As IEnumerable(Of Animal) = New Pets()
    pets.GetEnumerator()
End Sub
// Simple class hierarchy.
class Animal { }
class Cat : Animal { }
class Dog : Animal { }

// This class introduces ambiguity
// because IEnumerable<out T> is covariant.
class Pets : IEnumerable<Cat>, IEnumerable<Dog>
{
    IEnumerator<Cat> IEnumerable<Cat>.GetEnumerator()
    {
        Console.WriteLine("Cat");
        // Some code.
        return null;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        // Some code.
        return null;
    }

    IEnumerator<Dog> IEnumerable<Dog>.GetEnumerator()
    {
        Console.WriteLine("Dog");
        // Some code.
        return null;
    }
}
class Program
{
    public static void Test()
    {
        IEnumerable<Animal> pets = new Pets();
        pets.GetEnumerator();
    }
}

Bu örnekte, belirtilmeyen nasıl pets.GetEnumerator yöntemini seçer arasında Cat ve Dog.Bu kodda sorunlara neden olabilir.

Ayrıca bkz.

Başvuru

Farkı Func ve eylem genel Temsilciler için (C# ve Visual Basic) kullanma

Kavramlar

Varyans Generic arabirimlerden (C# ve Visual Basic)