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
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
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.