Varians tills du får VG Flashcards
IEnumerable<Apple> apples = new List<Apple>(); IEnumerable<Fruit> fruits = apples;
- Vad är den mest passande termen som beskriver förhållandet mellan IEnumerable< Apple> och IEnumerable< Fruit> i koden ovan?
a) Kovarians
b) Kontravarians
c) Invarians
Svar: a) Kovarians
Action<Fruit> fruitAction = fruit => Console.WriteLine("Nom nom"); Action<Apple> appleAction = fruitAction;
Vad är den mest passande termen som beskriver förhållandet mellan Action< Fruit> och Action< Apple> i koden ovan?
a) Kovarians
b) Kontravarians
c) Invarians
Svar: b) Kontravarians
Varianstermer i samband med generiska typer relaterar till hur typen T i I< T> kan vara:
a) Kovariant
b) Kontravariant
c) Invariant
d) Bivariant
Svaret är: c) Invariant
Motvering:
Varianstermer handlar om hur en generisk typ behåller relationen mellan typerna i sitt parametriserade argument. Invariant betyder att T i I< T> inte kan vara kovariant eller kontravariant.
Vad innebär kovarians när det gäller generiska typer?
a) Du kan använda en mer specifik typ som argument, och den behåller relationen.
b) Du kan använda en mer generell typ som argument, och den behåller relationen.
c) Det finns ingen relation mellan typerna.
d) Det handlar om att vara varierande.
Svar: a) Du kan använda en mer specifik typ som argument, och den behåller relationen.
Om typen A är en subtyp av typen B, vilken term beskriver situationen där I< B> är en subtyp av I< A>?
a) Kovarians
b) Kontravarians
c) Invarians
Svar: b) Kontravarians
Vad betyder invarians i samband med generiska typer?
a) Du kan använda en mer specifik typ som argument.
b) Du kan använda en mer generell typ som argument.
c) Det finns ingen relation mellan typerna.
d) Det handlar om att vara varierande.
Svar: c) Det finns ingen relation mellan typerna.
class Fruit { } class Apple : Fruit { } class FruitSequence { public virtual Fruit GetNext() => new Fruit(); } class AppleSequence : FruitSequence { public override Apple GetNext() => new Apple(); }
I det givna kodexemplet har vi två klasser, FruitSequence och AppleSequence, som ärver från varandra. FruitSequence har en virtuell metod GetNext, medan AppleSequence överskuggar den virtuella metoden och returnerar en instans av Apple.
- Vad är den mest relevanta termen som beskriver denna situation?
a) Kovarians
b) Kontravarians
c) Invarians
d) Polymorfism
Rättsvar: Kovarians
Motivering: Du använder en mer specifik typ där en mer generell förväntas.
class Fruit {} class Apple : Fruit {} IEnumerable<Apple> apples = new List<Apple>(); IEnumerable<Fruit> fruits = apples;
I det givna kodexemplet skapas en sekvens av äpplen, IEnumerable< Apple>, som fyller ett specifikt behov. Därefter försöker vi koppla den till en sekvens av frukter, IEnumerable< Fruit>.
- Vilken term bäst beskriver förhållandet mellan IEnumerable< Apple> och IEnumerable< Fruit> i koden?
a) Kovarians
b) Kontravarians
c) Invarians
Rättsvar: a) Kovarians
Motivering:
Förklaring: I det här fallet används kovarians, eftersom IEnumerable< T> är kovariant, och en IEnumerable< Apple> kan omvandlas (konverteras) till en IEnumerable< Fruit>. Detta är möjligt eftersom Apple är en subtyp av Fruit
class Fruit { } class Apple : Fruit { } class FruitSequence { public virtual Fruit GetNext() => new Fruit(); } class AppleSequence : FruitSequence { public override Apple GetNext() => new Apple(); }
Varför betraktas exemplet med FruitSequence som typsäkert?
a) FruitSequence är en producent av element av typ Fruit men inte en konsument. Den returnerar objekt av typ Fruit som output, men tar inte objekt av typ Fruit som input. Så en AppleSequence kan ersätta en FruitSequence eftersom allt den producerar kommer att vara objekt av typen Fruit (eftersom Apple : Fruit ).
b) FruitSequence är en konsument av element av typ Fruit men inte en producent. Den tar objekt av typ Fruit som input, men returnerar inte objekt av typ Fruit som output. Så en AppleSequence kan ersätta en FruitSequence eftersom allt den konsumerar kommer att vara objekt av typen Fruit (eftersom Apple : Fruit ).
c) FruitSequence är både producent och konsument av element av typ Fruit. Så en AppleSequence kan inte ersätta en FruitSequence eftersom allt den producerar och konsumerar måste vara av typen Fruit (eftersom Apple : Fruit ).
Svar: a) FruitSequence är en producent av element av typ Fruit men inte en konsument. Den returnerar objekt av typ Fruit som output, men tar inte objekt av typ Fruit som input. Så en AppleSequence kan ersätta en FruitSequence eftersom allt den producerar kommer att vara objekt av typen Fruit (eftersom Apple : Fruit ).
Anta att följande hierarki gäller: Apple är en subtyp av Fruit, och Fruit är en subtyp av Edible. Dessutom är T kovariant i I< T>.
Vilka av följande påståenden är sanna?
1. I<Apple> : I<Fruit> 2. I<Fruit> : I<Apple> 3. I<Apple> : I<Edible> 4. I<Edible> : I<Fruit>
Rättsvar:
1. I<Apple> : I<Fruit> 3. I<Apple> : I<Edible>
Motivering:
Eftersom T är kovariant i I< T>, kan en I< Apple> behandlas som en I< Fruit>, eftersom Apple är en subtyp av Fruit.
Eftersom Apple är en subtyp av Fruit, och Fruit är en subtyp av Edible, kan I< Apple> behandlas som I< Edible>.
- Vilket av följande påståenden är sant om kovarians och kontravarians i samband med generiska typer?
a) Kovarians innebär att subtyper kan använda mer generella typer.
b) Kontravarians innebär att subtyper kan använda mer generella typer.
c) Kovarians inverterar den “naturliga” typ-hierarkin.
Svar: a) Kovarians innebär att subtyper kan använda mer generella typer.
Motivering: Har du en påse äpple då har du också en påse frukt.
class Fruit {} class Apple : Fruit {} Action<Fruit> fruitJuicer = (Fruit x) => Console.WriteLine("Turning fruit into juice"); Action<Apple> appleJuicer = fruitJuicer;
I det givna kodexemplet används generiska delegater. En Action< Fruit> med namnet fruitJuicer konverterar frukt till juice. Därefter försöker vi koppla appleJuicer till fruitJuicer. Vad beskriver detta scenariot bäst?
a) Kovarians
b) Kontravarians
c) Invarians
Rättsvar: b) Kontravarians
Förklaring:
Action< T> är en kontravariant delegattyp i C#. Kontravarians möjliggör att en mer generell typ (i detta fall Action< Fruit>) kan ersättas med en mer specifik typ (i detta fall Action< Apple>), vilket är precis vad som händer när appleJuicer kopplas till fruitJuicer.
Anta att:
Apple : Fruit
Fruit : Edible
T är kontravariant i I< T> .
Vilka påståenden stämmer?
1. I<Apple> : I<Fruit> 2. I<Fruit> : I<Apple> 3. I<Apple> : I<Edible> 4. I<Edible> : I<Fruit>
Rättsvar: 2 och 4.
Kontra den naturliga följden.
Motivering:
I<Fruit> : I< Apple (Stämmer):
Eftersom T är kontravariant i I< T>, kan I< Fruit> betraktas som I< Apple>, eftersom kontravarians möjliggör användning av en mer generell typ som en mer specifik typ.</Fruit>
I< Edible> : I<Fruit>(Stämmer):
Eftersom T är kontravariant i I< T>, kan I< Edible> användas som I< Fruit>, eftersom kontravarians möjliggör användning av en mer generell typ som en mer specifik typ.</Fruit>
Anta att T i IList< T> var kovariant.
IList<Fruit> fruits = new List<Apple>(); fruits.Add(new Orange());
Vad stämmer?
1. Koden komplierar utan felmedelanden.
2. Koden kompilerar men ger exception
3. Koden komplilerar inte alls.
Rättsvar: 3. Koden kompilerar inte alls
Vad stämmer?
- Kovarians (Producer): En typparameter är kovariant (markerad med out), vilket innebär att den kan producera (ge ut) objekt av typen eller dess subtyper. I detta fall är den generiska typen en “producent” av objekt.
- Kontravarians (Consumer):
En typparameter är kontravariant (markerad med in), vilket innebär att den kan konsumera (ta emot) objekt av typen eller dess överordnade typer.
I detta fall är den generiska typen en “konsument” av objekt. - Invarians (varken eller): I en invariant generisk typ måste du använda exakt samma typ (och inte dess underordnade eller överordnade typer) som den generiska typen kräver. Invarians är standardbeteendet för generiska typer om du inte explicit markerar dem som kovarianta (med out) eller kontravarianter (med in).
Rättsvar: Alla så lär dig dom.