Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A .NET-keretrendszer 3.5-ös verziója variancia-támogatást vezetett be a metódusaláírások és a delegált típusok egyeztetéséhez a C# és a Visual Basic összes delegáltjában. Ez azt jelenti, hogy a meghatalmazottakhoz nem csak az egyező aláírással rendelkező metódusokat rendelheti hozzá, hanem olyan metódusokat is, amelyek több származtatott típust (kovarianciát) adnak vissza, vagy olyan paramétereket fogadnak el, amelyek kevésbé származtatott típusok (kontravarianciával) rendelkeznek, mint a delegált típus által megadottak. Ide tartoznak az általános és a nem általános meghatalmazottak is.
Vegyük például a következő kódot, amelynek két osztálya és két meghatalmazottja van: általános és nem általános.
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
A SampleDelegate vagy SampleDelegate(Of A, R) típusú delegátumok létrehozásakor az alábbi módszerek bármelyikét hozzárendelheti ezekhez a delegátumokhoz.
' 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
Az alábbi példakód a metódus aláírása és a delegált típusa közötti implicit konverziót szemlélteti.
' 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
További példákért tekintse meg a Delegátusok varianciájának használata (Visual Basic) és a Func és Action generikus delegátusok varianciájának használata (Visual Basic) című részt.
Variancia az általános típusparaméterekben
A .NET-keretrendszer 4-es és újabb verzióiban engedélyezheti a meghatalmazottak közötti implicit konverziót, így az általános típusparaméterek által meghatározott különböző típusú általános meghatalmazottak egymáshoz rendelhetők, ha a típusok egymástól öröklődnek a variancia által megkövetelt módon.
Az implicit átalakítás engedélyezéséhez explicit módon kell deklarálnia az általános paramétereket egy meghatalmazottban kovariantként vagy contravariantként a in vagy out kulcsszó használatával.
Az alábbi példakód bemutatja, hogyan hozhat létre olyan meghatalmazottat, aki kovariáns általános típusparaméterrel rendelkezik.
' 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
Ha csak a variancia támogatást használja a metódusaláírások és a delegálási típusok egyeztetéséhez, és nem használja a in és out kulcsszavakat, előfordulhat, hogy néha azonos lambda-kifejezésekkel vagy metódusokkal is példányosíthat delegáltakat, de nem rendelhet hozzá egy delegáltat egy másikhoz.
A következő kód példában SampleGenericDelegate(Of String) nem konvertálható explicit módon SampleGenericDelegate(Of Object)-ra, bár String örökli Object-t. Ezt a problémát az általános paraméter T kulcsszóval való megjelölésével out háríthatja el.
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
A .NET-keretrendszerben variant típusú paraméterekkel rendelkező általános meghatalmazottak
A .NET-keretrendszer 4 számos meglévő általános meghatalmazottban bevezette az általános típusparaméterek varianciájának támogatását:
Actiondelegáltak a System névtérből, például Action<T> és Action<T1,T2>Funcdelegáltak a System névtérből, például Func<TResult> és Func<T,TResult>A Predicate<T> meghatalmazott
A Comparison<T> meghatalmazott
A Converter<TInput,TOutput> meghatalmazott
További információkért és példákért lásd: A Func és az Action generikus delegáltak szórása (Visual Basic).
Általános delegáltban variáns típus paraméterek deklarálása
Ha egy általános delegált rendelkezik kovariant vagy contravariant általános típusparaméterekkel, akkor ezt nevezhetjük variáns általános delegáltnak.
Egy általános típusú paraméter kovariantot deklarálhat egy általános meghatalmazottban a out kulcsszó használatával. A kovariant típus csak metódus-visszatérési típusként használható, metódusargumentum-típusként nem. Az alábbi példakód bemutatja, hogyan deklarálhat kovariantikus általános meghatalmazottat.
Public Delegate Function DCovariant(Of Out R)() As R
Egy általános delegáltban a in kulcsszó használatával kontravariáns típusparamétert deklarálhat. A contravariant típus csak metódusargumentumok típusaként használható, metódusvisszautasítási típusként nem. Az alábbi példakód bemutatja, hogyan deklarálhat egy contravariant általános meghatalmazottat.
Public Delegate Sub DContravariant(Of In A)(ByVal a As A)
Fontos
ByRef a Visual Basicben a paraméterek nem jelölhetők meg variánsként.
A varianciát és a kovarianciát is támogathatja ugyanabban a delegáltban, de különböző típusparaméterek esetén. Ez az alábbi példában látható.
Public Delegate Function DVariant(Of In A, Out R)(ByVal a As A) As R
Variáns generikus delegáltak példányosítása és meghívása
A változatdelegáltak példányosítása és meghívása ugyanúgy lehetséges, mint az invariáns meghatalmazottak példányosítása és meghívása. Az alábbi példában a meghatalmazottat egy lambda kifejezés hozza létre.
Dim dvariant As DVariant(Of String, String) = Function(str) str + " "
dvariant("test")
Variant Generic Delegates kombinálása
Nem szabad változatdelegáltakat kombinálnod. A Combine metódus nem támogatja a változatdelegáltak konvertálását, és elvárja, hogy a meghatalmazottak pontosan azonos típusúak legyenek. Ez futásidejű kivételhez vezethet, ha a meghatalmazottakat a Combine metódussal (C# és Visual Basic) vagy az + operátorral (C#-ban) kombinálja, ahogyan az az alábbi kód példájában is látható.
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)
Érték- és referenciatípusok általános típusparamétereinek varianciája
Az általános típusparaméterek varianciája csak referenciatípusok esetén támogatott. Például, mivel az DVariant(Of Int) egy értéktípus, nem lehet implicit módon átalakítani DVariant(Of Object) vagy DVariant(Of Long) típusra.
Az alábbi példa azt mutatja be, hogy az általános típusparaméterek varianciája nem támogatott az értéktípusok esetében.
' 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
Visual Basic rugalmas delegált konverziója
A lazított delegált átalakítás nagyobb rugalmasságot tesz lehetővé a metódusaláírások és delegált típusok összehangolásában. Például lehetővé teszi, hogy kihagyja a paraméterek specifikációit, és kihagyja a függvény visszatérési értékeit, amikor metódust rendel egy delegálthoz. További információ: Relaxált delegált átalakítás.