Mi a lényege a kovariancia és ellentmondás a küldöttek verem túlcsordulás orosz

megkérdezték április 24-én, 18:36-kor

Nem világos, hogy a kovariancia és a kontravariancia hogyan épül fel. A példa azt mutatja, hogy egy küldött kétféleképpen hivatkozhat, különböző bemeneti és kimeneti paraméterekkel. Itt a kovariancia a ChangeIt change = IncrB;, és a contravariance ChangeIt change = IncrA; Általában a kovariancia és az ellentmondás meghatározása nem egyértelmű, túl zavarosak. - NaughtyBrain 19.04.14-én 19: 20-kor

Először is, nézzük meg, mi ez a verzió.

Legyen két osztályunk, az autó és a BMW. Nyilvánvaló, hogy a BMW egy autó alosztálya. minden bei egy gép.

Általában ezt mondják: "bárhol használja az autót. használhatja a BMW-t. " Ez valójában majdnem igaz, de nem egészen.

Példa: Ha van egy listája a gépekről, akkor nem használhatja a BMW listát. Miért? És itt az oka. Legyen egy Lista. és ezt a géplistát használja. Ezután ez a gépek listája. Add hozzá Zaporozhets Lanos-t, ugye? Itt kezdődnek a problémák. Ha a kód azt mondja:

Ha volt egy listánk, ami csak olvasható volt. akkor a probléma nem lett volna:

Szóval, mit kapunk? Annak ellenére, hogy a BMW autó, a BMW lista már nem feltétlenül az autók listája. De a BMW listája, amely csak olvasható, még mindig az autók listája.

Most vissza a variancia. A kovariancia általános értelemben szól, ha valami hasonló módon változik. Öröklési osztályok esetén a BMW helyett a BMW-t használhatjuk. és ugyanúgy, mint az IE számtalan használja az IE számozást .

Oké, ez hosszú bevezetés volt, most térjünk vissza a témához: a küldöttek kovarianciája. Legyen egy küldöttünk, az autó típusától függően. Változás az autójának meghatározásában BMW-ben. használhatom-e az új küldöttet a régi helyett?

Gondoljunk logikusan. Ha ilyen küldöttünk van:

(az Auto bevitelt veszi és Car más példányt ad ki), lehetséges-e helyettesíteni az ilyen típusú küldöttek által leírt funkciót:

Természetesen nem, mert a delegált bármely funkció bevitelére képes, és funkciónk csak a BMW-t akarja. Tehát itt nincs kovariancia: ez a funkció nem használható, ha erre a küldöttre van szükség.

De ha a variáns adattípusa (azaz az autó) csak a visszatérési típus helyzetében van:

akkor a helyén használhat ilyen típusú funkciót:

(ha bármilyen autó alkalmas, akkor a BMW is alkalmas).

Ez a küldöttek kovarianziója: ahol a küldöttet a kódban meg kell adnod tőle, akkor helyettesíthetsz egy kovariáns küldöttet.

Példakód, amely ezt használja:

Ellenkező esetben a kontravariancia működik: ott használhat egy olyan bázistípussal dolgozó küldöttet, ahol a származtatott típusú küldöttség várható. Ez funkcionális argumentumokkal működik:

Ez ugyanúgy működik, mint a kovariancia: ha a teszter bármilyen típusú gépre alkalmas, akkor a BMW-vel is dolgozhat.

A generikus delegált vagy interfész típusú paramétertípusok mindegyikét kváziánsnak vagy kontravariánsnak kell jelölni. Ez nem vezet semmilyen nemkívánatos következményhez, de lehetővé teszi, hogy a küldötted több forgatókönyvet használjon, és lehetővé teszi, hogy az általánosított küldött változójának típusát ugyanazt a delegált típushoz más paramétertípussal adja meg.

A paraméterek típusa lehet:

  • Változtatható. A paraméter típusa nem módosítható.
  • Kontravariáns. A paramétertípus osztályból osztályba konvertálható
    osztályból származik. A C #-ban az ellentmondásos típus
    a kulcsszó a. Kontravariáns paramétertípus
    csak akkor jelenik meg a bemeneti pozícióban, például mint
    a módszer érvei.
  • Covariance. A típus argumentum egy osztályból az egyik alaposztályába konvertálható. A C #-ban a kovariáns típust a kulcsszó jelöli. Az általánosított típus kovariáns paramétere csak a kimeneti pozícióban jelenhet meg, például a módszer visszatérési értékeként.

Tegyük fel, hogy a következő delegált típus létezik:

Itt a T-paramétert a "be" szavak jelölik. ami ellentmondásosnak tűnik, és a TResult paramétert a szóval jelöljük. ezáltal kovariánsnak bizonyul. Adjuk meg a következő változót:

Ez a típus a MyDelegate típushoz más paraméter-típusokkal érhető el:

Ez azt jelzi, hogy az fn1 olyan függvényre utal, amely egy Objektumot fogad és egy ArgumentException-ot ad vissza. Az fn2 változó megpróbál hivatkozni egy olyan módszerre, amely egy Stringet kap és egy Exception-ot visz vissza. Mivel egy Stringet átadhatunk egy olyan eljárásnak, amelyhez egy objektumtípus szükséges (a String típusa objektumból származik), és az ArgumentException visszaküldésének módszere. értelmezhető kivételként (az ArgumentException típusa az Exception-ből származik), az itt bemutatott kódot össze kell állítani, és a fordítási szakaszban a biztonság megőrzése megmarad.

Megjegyzés: A változat csak akkor működik, ha a fordító beállíthatja a típusok közötti kapcsolatok átalakítását. Más szóval, a változatosság nem alkalmazható jelentős típusokra, mivel szükség van a boxolásra.

Kapcsolódó cikkek