Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
.NET Framework 3.5 heeft ondersteuning voor variantie geïntroduceerd voor methodehandtekeningen die overeenkomen met delegate-types in alle delegates in C# en Visual Basic. Dit betekent dat u niet alleen methoden kunt toewijzen aan gedelegeerden die overeenkomende handtekeningen hebben, maar ook methoden die meer afgeleide typen (covariantie) retourneren of parameters accepteren die minder afgeleide typen (contravariantie) hebben dan die zijn opgegeven door het gemachtigdetype. Dit omvat zowel algemene als niet-algemene gemachtigden.
Denk bijvoorbeeld aan de volgende code, die twee klassen en twee gemachtigden heeft: algemeen en niet-algemeen.
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
Wanneer u gemachtigden van de SampleDelegate of SampleDelegate(Of A, R) typen maakt, kunt u een van de volgende methoden toewijzen aan deze gemachtigden.
' 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
In het volgende codevoorbeeld ziet u de impliciete conversie tussen de methodehandtekening en het type gemachtigde.
' 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
Voor meer voorbeelden, zie Variantie gebruiken in Gedelegeerden (Visual Basic) en Variantie gebruiken voor Func en Action Generic Delegates (Visual Basic).
Afwijking in algemene typeparameters
In .NET Framework 4 en hoger kunt u impliciete conversie tussen delegates inschakelen, zodat generieke delegates met verschillende typen die door generieke typeparameters gespecificeerd zijn, aan elkaar kunnen worden gekoppeld, mits de typen van elkaar afgeleid zijn, zoals vereist door variantie.
Als u impliciete conversie wilt inschakelen, moet u expliciet algemene parameters in een gemachtigde declareren als covariant of contravariant met behulp van het in of out trefwoord.
In het volgende codevoorbeeld kunt u zien hoe u een gedelegeerde kunt maken met een covariant generiek typeparameter.
' 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
Als u alleen variantieondersteuning gebruikt om methodehandtekeningen te vergelijken met gedelegeerdentypen en de in trefwoorden out niet gebruikt, kunt u soms gedelegeerden instantiëren met identieke lambda-expressies of -methoden, maar u kunt geen gedelegeerde aan een andere gemachtigde toewijzen.
In het volgende codevoorbeeld kan SampleGenericDelegate(Of String) niet expliciet worden geconverteerd naar SampleGenericDelegate(Of Object), hoewel StringObject erft. U kunt dit probleem oplossen door de algemene parameter T te markeren met het out trefwoord.
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
Algemene gemachtigden met varianttypeparameters in .NET Framework
.NET Framework 4 heeft variantieondersteuning geïntroduceerd voor algemene typeparameters in verschillende bestaande algemene gemachtigden:
Actionvertegenwoordigers uit de System naamruimte, bijvoorbeeld Action<T> en Action<T1,T2>Funcvertegenwoordigers uit de System naamruimte, bijvoorbeeld Func<TResult> en Func<T,TResult>De Predicate<T> gedelegeerde
De Comparison<T> gedelegeerde
De Converter<TInput,TOutput> gedelegeerde
Zie Variantie gebruiken voor Func en Action Generic Delegates (Visual Basic) voor meer informatie en voorbeelden.
Parameters voor varianttype declareren in algemene gemachtigden
Als een generieke gedelegeerde covariante of contravariante generieke typeparameters heeft, kan deze worden aangeduid als een variant generieke gedelegeerde.
U kunt een algemene parametercovariant in een algemene gemachtigde declareren met behulp van het out trefwoord. Het covarianttype kan alleen worden gebruikt als retourtype voor een methode en niet als een type methodeargumenten. In het volgende codevoorbeeld ziet u hoe u een covariant algemene gemachtigde declareert.
Public Delegate Function DCovariant(Of Out R)() As R
U kunt een generieke typeparameter contravariant verklaren in een generieke gedelegeerde door het trefwoord in te gebruiken. Het contravariante type kan alleen worden gebruikt als type voor methode-argumenten en niet als methode retourtype. In het volgende codevoorbeeld ziet u hoe u een contravariante generieke gedelegeerde declareert.
Public Delegate Sub DContravariant(Of In A)(ByVal a As A)
Belangrijk
ByRef parameters in Visual Basic kunnen niet worden gemarkeerd als variant.
Je kunt ook zowel variantie als covariantie in dezelfde delegate ondersteunen, maar voor verschillende typeparameters. Dit wordt weergegeven in het volgende voorbeeld.
Public Delegate Function DVariant(Of In A, Out R)(ByVal a As A) As R
Generieke variant gedelegeerden instantiëren en aanroepen
U kunt variantendelegeringen instantiëren en aanroepen, net zoals u invariante gedelegeerden instantieert en aanroept. In het volgende voorbeeld wordt de gemachtigde geïnstantieerd door een lambda-expressie.
Dim dvariant As DVariant(Of String, String) = Function(str) str + " "
dvariant("test")
Variërende generieke delegates combineren
U zou geen variantafgevaardigden moeten combineren. De Combine methode biedt geen ondersteuning voor conversie van variant-delegaten en verwacht dat delegaten precies van hetzelfde type zijn. Dit kan leiden tot een runtime-uitzondering wanneer u gemachtigden combineert met behulp van de Combine methode (in C# en Visual Basic) of met behulp van de + operator (in C#), zoals wordt weergegeven in het volgende codevoorbeeld.
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)
Variantie in algemene typeparameters voor waarde- en verwijzingstypen
Variantie voor algemene typeparameters wordt alleen ondersteund voor referentietypen. Kan bijvoorbeeld DVariant(Of Int)niet impliciet worden geconverteerd naar DVariant(Of Object) of DVariant(Of Long), omdat een geheel getal een waardetype is.
In het volgende voorbeeld ziet u dat variantie in algemene typeparameters niet wordt ondersteund voor waardetypen.
' 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 dVariantInt 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 dVariantObject As DInvariant(Of Object) = dInt
' Dim dVariantLong As DInvariant(Of Long) = dInt
End Sub
Ontspannen conversie van gemachtigden in Visual Basic
Ontspannen conversie van gemachtigden maakt meer flexibiliteit mogelijk bij het vergelijken van methodehandtekeningen met gedelegeerdentypen. U kunt bijvoorbeeld parameterspecificaties weglaten en functiewaarden weglaten wanneer u een methode aan een gemachtigde toewijst. Zie Ontspannen conversie van gedelegeerden voor meer informatie.