Sdílet prostřednictvím


Odchylky v delegátech (C# and Visual Basic)

.NET Framework 3.5 a Visual Studio 2008 byla zavedena podpora odchylka odpovídající metodu podpisy s typy delegáta ve všech Delegáti v jazyce C# a Visual Basic.To znamená, že můžete přiřadit deleguje pouze metody, které mají odpovídající podpisy, ale také metody, které vracejí více odvozené typy (kovariance) nebo který přijmout parametry, které obsahují méně odvozené typy (contravariance), než je určený typ delegáta.To zahrnuje obecný a obecné delegátů.

Zvažte například následující kód, který má dvě třídy a dva delegáty: obecný a obecné.

Public Class First
End Class 

Public Class Second
    Inherits First
End Class 

Public Delegate Function SampleDelegate(ByVal a As Second) As First
Public Delegate Function SampleGenericDelegate(Of A, R)(ByVal a As A) As R
public class First { }
public class Second : First { }
public delegate First SampleDelegate(Second a);
public delegate R SampleGenericDelegate<A, R>(A a);

Při vytvoření zástupci SampleDelegate nebo SampleGenericDelegate<A, R> (SampleDelegate(Of A, R) v jazyce Visual Basic) typů, můžete přiřadit libovolnou z následujících metod těchto delegátů.

' Matching signature. 
Public Shared Function ASecondRFirst(
    ByVal second As Second) As First
    Return New First()
End Function 

' The return type is more derived. 
Public Shared Function ASecondRSecond(
    ByVal second As Second) As Second
    Return New Second()
End Function 

' The argument type is less derived. 
Public Shared Function AFirstRFirst(
    ByVal first As First) As First
    Return New First()
End Function 

' The return type is more derived  
' and the argument type is less derived. 
Public Shared Function AFirstRSecond(
    ByVal first As First) As Second
    Return New Second()
End Function
// Matching signature. 
public static First ASecondRFirst(Second first)
{ return new First(); }

// The return type is more derived. 
public static Second ASecondRSecond(Second second)
{ return new Second(); }

// The argument type is less derived. 
public static First AFirstRFirst(First first)
{ return new First(); }

// The return type is more derived  
// and the argument type is less derived. 
public static Second AFirstRSecond(First first)
{ return new Second(); }

Následující příklad kódu ukazuje implicitní převod mezi podpis metody a typ delegáta.

' Assigning a method with a matching signature  
' to a non-generic delegate. No conversion is necessary. 
Dim dNonGeneric As SampleDelegate = AddressOf ASecondRFirst
' Assigning a method with a more derived return type  
' and less derived argument type to a non-generic delegate. 
' The implicit conversion is used. 
Dim dNonGenericConversion As SampleDelegate = AddressOf AFirstRSecond

' Assigning a method with a matching signature to a generic delegate. 
' No conversion is necessary. 
Dim dGeneric As SampleGenericDelegate(Of Second, First) = AddressOf ASecondRFirst
' Assigning a method with a more derived return type  
' and less derived argument type to a generic delegate. 
' The implicit conversion is used. 
Dim dGenericConversion As SampleGenericDelegate(Of Second, First) = AddressOf AFirstRSecond
// Assigning a method with a matching signature  
// to a non-generic delegate. No conversion is necessary.
SampleDelegate dNonGeneric = ASecondRFirst;
// Assigning a method with a more derived return type  
// and less derived argument type to a non-generic delegate. 
// The implicit conversion is used.
SampleDelegate dNonGenericConversion = AFirstRSecond;

// Assigning a method with a matching signature to a generic delegate. 
// No conversion is necessary.
SampleGenericDelegate<Second, First> dGeneric = ASecondRFirst;
// Assigning a method with a more derived return type  
// and less derived argument type to a generic delegate. 
// The implicit conversion is used.
SampleGenericDelegate<Second, First> dGenericConversion = AFirstRSecond;

Další příklady naleznete v tématu Použití odchylek v delegátech (C# and Visual Basic) a Použití odchylek pro obecné delegáty Func a Action (C# and Visual Basic).

Odchylka v obecné parametry typu

V.NET Framework 4, implicitní převod mezi delegáty, můžete povolit, aby obecný delegátů, které mají různé typy určené parametry obecný typ lze přiřadit, pokud jsou typy dědí od sebe podle odchylka.

Chcete-li povolit implicitní převod musí explicitně deklarovat obecné parametry v delegáta jako covariant nebo pomocí contravariant in nebo out klíčové slovo.

Následující příklad kódu ukazuje, jak vytvořit delegát, který má covariant obecný typ parametru.

' Type T is declared covariant by using the out keyword. 
Public Delegate Function SampleGenericDelegate(Of Out T)() As T
Sub Test()
    Dim dString As SampleGenericDelegate(Of String) = Function() " " 
    ' You can assign delegates to each other, 
    ' because the type T is declared covariant. 
    Dim dObject As SampleGenericDelegate(Of Object) = dString
End Sub
// Type T is declared covariant by using the out keyword. 
public delegate T SampleGenericDelegate <out T>();

public static void Test()
{
    SampleGenericDelegate <String> dString = () => " ";

    // You can assign delegates to each other, 
    // because the type T is declared covariant.
    SampleGenericDelegate <Object> dObject = dString;           
}

Pokud používáte pouze podporu odchylka odpovídající podpisy, metoda delegovat typy a nepoužívejte in a out klíčová slova, může najít někdy můžete konkretizovat Delegáti identické lambda výrazy nebo metod, ale není možné přiřadit jeden delegát do jiného.

V následujícím příkladu kódu SampleGenericDelegate<String> nelze explicitně převést na SampleGenericDelegate<Object> (SampleGenericDelegate(Of String) na SampleGenericDelegate(Of Object) v jazyce Visual Basic), ačkoli String dědí Object.Tento problém můžete vyřešit označením obecný parametr T se out klíčové slovo.

Public Delegate Function SampleGenericDelegate(Of T)() As T
Sub Test()
    Dim dString As SampleGenericDelegate(Of String) = Function() " " 

    ' You can assign the dObject delegate 
    ' to the same lambda expression as dString delegate 
    ' because of the variance support for  
    ' matching method signatures with delegate types. 
    Dim dObject As SampleGenericDelegate(Of Object) = Function() " " 

    ' The following statement generates a compiler error 
    ' because the generic type T is not marked as covariant. 
    ' Dim dObject As SampleGenericDelegate(Of Object) = dString 


End Sub
public delegate T SampleGenericDelegate<T>();

public static void Test()
{
    SampleGenericDelegate<String> dString = () => " ";

    // You can assign the dObject delegate 
    // to the same lambda expression as dString delegate 
    // because of the variance support for  
    // matching method signatures with delegate types.
    SampleGenericDelegate<Object> dObject = () => " ";

    // The following statement generates a compiler error 
    // because the generic type T is not marked as covariant. 
    // SampleGenericDelegate <Object> dObject = dString;



}

Obecný delegátů, které mají varianty zadejte parametry v.NET Framework

.NET Framework 4 zavádí podporu odchylka pro obecný typ parametry v několika existujících Delegáti obecný:

Další informace a příklady naleznete v tématu Použití odchylek pro obecné delegáty Func a Action (C# and Visual Basic).

Deklarování typ Variant parametry v generické Delegáti

Pokud má delegát obecný covariant nebo parametry obecného typu contravariant, jej lze odkazovat jako varianty obecný delegovat.

Můžete deklarovat obecný typ parametru covariant v obecné delegát pomocí out klíčové slovo.Covariant typ lze použít pouze jako návratový typ metody a nikoli jako typ argumenty metody.Následující příklad kódu ukazuje, jak covariant obecný delegáta deklarovat.

Public Delegate Function DCovariant(Of Out R)() As R
public delegate R DCovariant<out R>();

Můžete obecný typ parametru contravariant v obecné delegáta deklarovat pomocí in klíčové slovo.Typ contravariant lze použít pouze jako typ argumenty metody a nikoli jako návratový typ metody.Následující příklad kódu ukazuje, jak contravariant obecný delegáta deklarovat.

Public Delegate Sub DContravariant(Of In A)(ByVal a As A)
public delegate void DContravariant<in A>(A a);
Důležitá poznámkaDůležité

ByRefParametry v jazyce Visual Basic a ref a out parametry v jazyce C# a nelze označit jako typ variant.

Je také možné podporovat rozptyl a kovariance stejného delegáta, ale pro jiný typ parametrů.Toto je znázorněno v následujícím příkladu.

Public Delegate Function DVariant(Of In A, Out R)(ByVal a As A) As R
public delegate R DVariant<in A, out R>(A a);

Konkretizace a vyvolání obecný Delegáti varianty

Můžete konkretizovat a vyvolat varianty Delegáti jako konkretizovat a vyvolat výchozí delegátů.Následující příklad vytvoření delegát instance lambda výraz.

Dim dvariant As DVariant(Of String, String) = Function(str) str + " "
dvariant("test")
DVariant<String, String> dvariant = (String str) => str + " ";
dvariant("test");

Diakritické znaménko obecný Delegáti varianty

Delegáti varianty by neměli kombinovat.Combine Metodu nepodporuje převod varianty delegáta a očekává delegátů být stejného typu.To může vést k výjimku běhu při kombinaci prostřednictvím delegátů Combine metody (v C# a Visual Basic) nebo pomocí + operátor (v jazyce C#), jak je znázorněno v následujícím příkladu kódu.

Dim actObj As Action(Of Object) = Sub(x) Console.WriteLine("object: {0}", x)
Dim actStr As Action(Of String) = Sub(x) Console.WriteLine("string: {0}", x)

' The following statement throws an exception at run time. 
' Dim actCombine = [Delegate].Combine(actStr, actObj)
Action<object> actObj = x => Console.WriteLine("object: {0}", x);
Action<string> actStr = x => Console.WriteLine("string: {0}", x);
// All of the following statements throw exceptions at run time. 
// Action<string> actCombine = actStr + actObj; 
// actStr += actObj; 
// Delegate.Combine(actStr, actObj);

Odchylka v obecné parametry typu hodnoty a typy odkazů

Odchylka pro obecný typ parametrů je podporováno pouze typy odkazů.Například DVariant<int> (DVariant(Of Int) v jazyce Visual Basic) nelze implicitně převést na DVariant<Object> nebo DVaraint<long> (DVariant(Of Object) nebo DVaraint(Of Long) v jazyce Visual Basic), protože hodnota typu integer.

Následující příklad ukazuje, že odchylka v obecném typu parametry nejsou podporovány pro typy hodnot.

' The type T is covariant. 
Public Delegate Function DVariant(Of Out T)() As T
' The type T is invariant. 
Public Delegate Function DInvariant(Of T)() As T
Sub Test()
    Dim i As Integer = 0
    Dim dInt As DInvariant(Of Integer) = Function() i
    Dim dVaraintInt As DVariant(Of Integer) = Function() i

    ' All of the following statements generate a compiler error 
    ' because type variance in generic parameters is not supported 
    ' for value types, even if generic type parameters are declared variant. 
    ' Dim dObject As DInvariant(Of Object) = dInt 
    ' Dim dLong As DInvariant(Of Long) = dInt 
    ' Dim dVaraintObject As DInvariant(Of Object) = dInt 
    ' Dim dVaraintLong As DInvariant(Of Long) = dInt 
End Sub
// The type T is covariant. 
public delegate T DVariant<out T>();

// The type T is invariant. 
public delegate T DInvariant<T>();

public static void Test()
{
    int i = 0;
    DInvariant<int> dInt = () => i;
    DVariant<int> dVariantInt = () => i;

    // All of the following statements generate a compiler error 
    // because type variance in generic parameters is not supported 
    // for value types, even if generic type parameters are declared variant. 
    // DInvariant<Object> dObject = dInt; 
    // DInvariant<long> dLong = dInt; 
    // DVariant<Object> dVariantObject = dVariantInt; 
    // DVariant<long> dVariantLong = dVariantInt;            
}

Převod uvolněné delegát v jazyce Visual Basic

Převod uvolněné delegát v jazyce Visual Basic 2008 umožňuje větší flexibilitu v odpovídající metodu podpisy s typy delegáta.Například umožňuje vynechat parametr specifikace a vynechat vrácené hodnoty funkce delegátovi přiřadíte metodu.Další informace naleznete v tématu Volný převod delegáta (Visual Basic).

Viz také

Úkoly

Postupy: Kombinování delegátů (vícesměroví delegáti) (Průvodce programováním v C#)

Referenční dokumentace

Použití odchylek pro obecné delegáty Func a Action (C# and Visual Basic)

Další zdroje

Obecné typy v architektuře .NET Framework