Covariance și contravariance în șabloanele universale

Termenii "covarianță" și "contravariență" se referă la posibilitatea utilizării unui tip de adâncime mai mică sau mai mare decât cea specificată inițial. Parametrii tipurilor universale sprijină covarianța și contravariența și oferă o mai mare flexibilitate în alocarea și utilizarea tipurilor universale. Mai jos sunt definițiile termenilor "covarianță", "contravarianță" și "invarianță" în contextul sistemului de tip. Acest exemplu presupune că există o clasă de bază numită Bază și o clasă derivată numită Derivat.







Vă permite să utilizați un tip cu o adâncime mai mare decât cea specificată inițial.

Exemplu de numărare (IEnumerable (Of Derived) în Visual Basic) poate fi atribuită unei variabile de tipul IEnumerable.

Vă permite să utilizați un tip mai generic (cu o adâncime mai mică de moștenire) decât cel specificat inițial.

Exemplu de numărare (IEnumerable (Of Base) din Visual Basic) poate fi atribuită unei variabile de tipul IEnumerable.

Aceasta înseamnă că puteți utiliza numai tipul specificat inițial. Astfel, parametrul tipului universal invariabil nu este nici covariantic, nici contravariant.

Exemplu de numărare (IEnumerable (Of Base) în Visual Basic) nu poate fi atribuită unei variabile de tipul IEnumerable. și invers.

Parametrii de tip Covariant vă permit să creați sarcini care par foarte asemănătoare cu polimorfismul normal (C # Programming Guide). după cum arată următorul cod.

Acest lucru poate părea un pas înapoi, dar este un cod sigur pentru tip care este compilat și executat. Lambda corespunde delega, care i se atribuie, și determină metoda care are un singur parametru de tipul de bază și nu are nici o valoare de întoarcere. Delegatul rezultat poate fi atribuit unei variabile de acțiune. deoarece parametrul T al delegatului Action este contravariantă. Codul este sigur pentru tip deoarece T specifică tipul parametrului. Atunci când un delegat de acțiune se numește ca și cum ar fi un delegat al tipului de acțiune. argumentul său trebuie să fie un argument de tip Derived. Acest argument poate fi întotdeauna trecut în siguranță la metoda de bază, deoarece parametrul metodei este un parametru de tip Base.

În general, un parametru de tip covariant poate fi utilizat ca tip de retur al unui delegat, iar parametrii tip contravariant pot fi utilizați ca tipuri de parametri. Pentru interfață, parametrii de tip covariant pot fi utilizați ca tipuri de retur de metode de interfață, iar parametrii tip contravariant pot fi utilizați ca tipuri de parametru de tip interfață.

Împreună, covarianța și contravariatul sunt numite variații. Parametrul tipului universal, care nu este marcat ca covarianță sau contravariantă, este numit invariabil. Informații succinte despre variabilitatea limbii de rulare comune:







În cadrul .NET Framework 4, următoarele interfețe și tipuri de delegați au parametri de tip covariant și / sau contravariant.

Tipul interfeței universale sau al metodei delegate universale poate avea atât parametri de tip covariant cât și contravarianți.

Variabilitatea se aplică numai tipurilor de referință; dacă specificați un tip de valoare pentru un parametru de tip variante, acest parametru de tip este invariabil pentru tipul creat ca rezultat.

Variabilitatea nu este aplicabilă unirii delegațiilor. Prin urmare, pentru doi delegați ai tipurilor de acțiune și acțiunea (Acțiune (derivată) și Acțiune (de bază) în Visual Basic), nu puteți combina primul delegat cu cel de-al doilea, deși rezultatul este un tip securizat. Variabilitatea vă permite să atribuiți unui al doilea delegat unei variabile de acțiune. Dar delegații pot fi combinați numai dacă tipul lor se potrivește exact.

În următoarele subsecțiuni, parametrii de tip covariant și contravariant sunt descriși în detaliu.

În cadrul .NET Framework 4, următoarele interfețe și tipuri de delegați au parametri de tip covariant și / sau contravariant. Unele kernel-uri de automatizare UI maschează orice diferențe în structurile aparținând diferitelor părți ale UI. Aceasta înseamnă că delegații pot fi alocați variabilelor care au mai multe tipuri de parametri derivați și (în cazul metodelor generice delegate Func) mai puține tipuri de returnare derivate.

Ultimul parametru al unui tip generic metode generice de delegați func indică tipul de valoarea returnată în semnătură delegat. El este un covariantă (cuvânt cheie afară), în timp ce restul parametrilor de tip generice sunt contravariant (cuvânt cheie din).

Acest lucru este ilustrat în următorul cod. Prima parte a codului definește o clasă numită Base. clasă cu numele Derived. moștenind din clasa Base. și o altă clasă cu o metodă statică (partajată în Visual Basic) și cu numele MyMethod. Această metodă ia o instanță a clasei de bază și returnează o instanță a clasei Derived. (. Dacă argumentul este un exemplu de metodă mymethod derivate revine, în cazul în care argumentul este un exemplu de metoda de bază mymethod returnează o nouă instanță a clasei derivate ..) În principal exemplu funcția () creează o instanță de func (Func (De bază, Derived) în Visual Basic) care reprezintă metoda MyMethod. și este stocată în variabila f1.

Începând cu .NET Framework versiunea 2.0, CLR acceptă note variate pentru parametrii de tip universal. Versiunile anterioare .NET Framework 4 singura modalitate de a determina clasa generică care are o astfel de notă, a fost utilizarea MSIL limbii, fie prin compilarea de clasă folosind programul Ilasm.exe (IL Assembler). sau prin introducerea acestuia într-un ansamblu dinamic.

Parametrul de tip covarianță este marcat cu cuvântul cheie "out" (cuvântul cheie extern în Visual Basic, cuvântul cheie + MSIL Assembler). Parametrul de tip covariant poate fi folosit ca valoare de retur a metodei care aparține interfeței sau ca tip de retur al delegatului. Parametrul de tip covariante nu poate fi folosit ca o constrângere de tip universală pentru metodele de interfață.

Dacă metoda interfeței are un parametru cu tipul metodei delegate universale, parametrul de tip covariante al acestui tip de interfață poate fi utilizat pentru a specifica parametrul de tip contravariant al acestui tip de delegat.

Parametrul tipului contravariant este marcat cu cuvântul cheie din (în cuvântul cheie din Visual Basic, cuvântul cheie pentru MSIL Assembler). Puteți utiliza parametrul de tip contravariant ca tip de parametru al metodei care aparține interfeței sau ca tip al parametrului delegat. Parametrul de tip contravariant poate fi utilizat ca o constrângere de tip universal pentru metoda interfeței.

Parametrii unui tip de variantă pot avea numai tipuri de interfețe și tipuri de delegate. Tipul de interfață sau tipul de delegat poate avea atât parametri covarianți, cât și contravenționali.

Limbile Visual Basic și C # nu se permite să încalce regulile de utilizare a parametrilor covariant și tipul contravariant sau adăugați note sau parametri contravariance covarianță tip cu o altă persoană decât interfețele și delegați de tip. Unele kernel-uri de automatizare UI maschează orice diferențe în structurile aparținând diferitelor părți ale UI.







Trimiteți-le prietenilor: