Soci (Soczó Zsolt) szakmai blogja

2011.02.01.

C# 4 Covariance

Filed under: .NET,.NET 4,C#,Szakmai élet — Soczó Zsolt @ 16:27

.NET 4-es tanfolyamhoz írok egy prezentációt. A co és -contravarianciát próbálom érhetővé tenni. Kb. ez van a slideokon:

Variance annotations – covariance 1.

class Allat { }
class Kutya : Allat { }

interface IAllatGyar<T> where T : Allat
{
T Create();
}
class AllatGyar<T> : IAllatGyar<T> where T : Allat
{
public T Create()
{
return default(T);
}
}
AllatGyar<Kutya> kutyagyar = new AllatGyar<Kutya>();
IAllatGyar<Allat> allatGyar = kutyagyar; //cast, jogos?
Allat a = allatGyar.Create(); //mit ad vissza, típusbiztos?

Type ordering
Kutya <: Allat - A Kutya az Allat osztály leszámazottja k : Kutya - k a Kutya típus egy példánya Ha k : Kutya és Kutya <: Allat, akkor k : Allat (Liskov féle helyettesítési elv) Igaz-e, hogy ha Kutya <: Allat, akkor IAllatgyar< Kutya > <: IAllatgyar< Allat > ?
Egy Kutya példány implicit castolható Allattá. Az Allatgyar< Kutya > típusbiztosan castolható-e Allatgyar< Allat >-tá?
Ha csak kimeneti paraméterként vagy visszatérési értékként jön ki T, akkor igen, mert Kutya <: Allat, így minden kimeneti paraméternél a Allat referenciával biztonságosan elérhető egy leszármazott Kutya példány is. Ha igen, akkor T covariant, mert a típusparaméterek type orderingje érvényes a típust használó generikus típusra is, ugyanabban a sorrendben (Kutya <: Allat ==> IAllatgyar< Kutya > <: IAllatgyar< Allat >).
C# 4-ben az interfész metódus vagy delegate szignatúrában az out kulcsszó jelzi ezt:

interface IAllatgyar<out T>.

Amikor ez nem megy:

class Allat { }
class Kutya : Allat { }

interface IAllatGyar<T> where T : Allat
{
T Create();
void Valami(T t); //T befelé megy!
}

AllatGyar<Kutya> kutyagyar = new AllatGyar<Kutya>();
IAllatGyar<Allat> allatGyar = kutyagyar;

kutyagyar.Valami(new Kutya()); //Ez nyilván ok

allatGyar.Valami(new Lo()); //És ez???

Ha bemeneti paraméter is T, akkor az IAllatgyar< Allat > statikus típuson, amely valójában a IAllatgyar< Kutya > dinamikus típusra mutat átadható lenne más állat is, pl. Ló, amely szintén Allat leszármazott, de az nyilvánvaló runtime hibát okozna. Ezért nem lehet covariant T, ha az interfészen bemenetként is szerepel T.

Érhető ez így? Bármilyen javaslatot szívesen fogadok. A delegatekhez is írok persze anyagot, ez csak az eleje.

4 Comments

  1. “Az Allatgyar típusbiztosan castolható-e Allatgyar-tá?”
    Csunya lenne, ha a sajat osztalyara nem lenne castolhato. Viszont a ragozast elbokted.

    Egyebkent sztem az a baj, hogy idekeverted mar az elejebe a Generic-eket. Nem tudom, hogy a C# hogy all vele, de a Java-ban a Generic es a sima inheritance kicsit meg van kavarva.

    Comment by hrongyorgy — 2011.02.02. @ 08:51

  2. Oh, a generikus kacsacsőrök lemaradtak a html miatt, így elég értelmetlen lett, bocs. Javítom.

    Comment by Soczó Zsolt — 2011.02.02. @ 10:46

  3. Lehet a 2.0-s delegate varianciákat rakom előre majd, és utána a 4.0-s generikusokat…

    Comment by Soczó Zsolt — 2011.02.02. @ 10:49

  4. Tipp: &lt; = < es &gt; = >

    Comment by hrongyorgy — 2011.02.09. @ 21:38

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress