Varians tills du får VG Flashcards

1
Q
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

A

Svar: a) Kovarians

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q
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

A

Svar: b) Kontravarians

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Varianstermer i samband med generiska typer relaterar till hur typen T i I< T> kan vara:

a) Kovariant
b) Kontravariant
c) Invariant
d) Bivariant

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

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.

A

Svar: a) Du kan använda en mer specifik typ som argument, och den behåller relationen.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

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

A

Svar: b) Kontravarians

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

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.

A

Svar: c) Det finns ingen relation mellan typerna.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q
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

A

Rättsvar: Kovarians

Motivering: Du använder en mer specifik typ där en mer generell förväntas.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
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

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q
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 ).

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

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

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
  • 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.

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
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

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

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

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>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

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.

A

Rättsvar: 3. Koden kompilerar inte alls

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Vad stämmer?

  1. 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.
  2. 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.
  3. 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).
A

Rättsvar: Alla så lär dig dom.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q
class Container<T>
{
    private T data;

    public Container(T data)
    {
        this.data = data;
    }

    public T GetData()
    {
        return data;
    }
}

Container<string> container = new Container<string>("Hello");

string data = container.GetData(); 
int length = data.Length; 

I följande kod vad används?
1. Kontravarians.
2. Invarians.
3. Kovarians.

A

Rättsvar: 2. Invarians.

Motivering:

I exemplet ovan är Container< T> invariant i typen T. Det innebär att när du skapar en Container< string>, måste du använda exakt samma typ (string) när du hämtar data från containern. Du kan inte använda en överordnad typ (t.ex. object) som argument när du hämtar data, och du kan inte använda en underordnad typ (t.ex. StringBuilder) heller.

17
Q

Fråga: I vilket scenario skulle invarians vara mest lämpligt när man definierar generiska gränssnitt i C#?

A) När du vill tillåta subtyper att användas flexibelt i stället för bas- eller supertyper.
B) När säkerhet och dataintegritet är avgörande, och varje operation på typen måste vara strikt begränsad till exakt den deklarerade typen.
C) När du behöver möjligheten att byta ut typer med deras bas- eller drivna typer utan problem vid kompilering eller körning.

A

Svar: B

18
Q

Enbart exempel kod:

public delegate TOutput Converter<in TInput, out TOutput>(TInput input);

Converter<object, string> reference = (object obj) => obj.ToString();
Converter<string, string> operation = reference;

Fråga: Vilken typ av varians tillämpas i delegaten ‘Converter’ som gör tilldelningen av ‘operation’ giltig?

A) Bara kovarians
B) Bara kontravarians
C) Både kovarians och kontravarians

A

Svar: C

19
Q

Vad blir output?

interface IProcessor<in T>
{
    string Process(T input);
}

class StringProcessor : IProcessor<object>
{
    public string Process(object input) => "Processed: " + input.ToString();
}

var processor = new StringProcessor();
Console.WriteLine(processor.Process("TestInput"));

Fråga: Vad blir utskriften av ovanstående kod?

A) “Processed: TestInput”
B) Kompileringsfel på grund av felaktig typomvandling.
C) Körtidsfel eftersom IProcessor är kontravariant.

A

Svar: A

20
Q

kod:

IEnumerable<object> objects = new List<string>();

Fråga: Kompilerar koden ovan korrekt?

A) Ja, eftersom IEnumerable stöder kovarians.
B) Nej, eftersom IEnumerable är invariant och inte tillåter denna typ av typomvandling.
C) Ja, men ett undantag kommer att kastas vid körning.

A

Svar: A

21
Q
class  Animal{}
class Tiger : Animal {}

Action<Tiger> tigerPrinter = (Tiger tiger) => Console.WriteLine(tiger.GetType().Name);

Action<_ _ _ _ _> printer = tigerPrinter;

Fråga: Vilken typ bör ersätta de tomma understrykningarna för att koden ska vara korrekt enligt konceptet av kontravarians inom delegater?

A) Object
B) Animal
C) Tiger

A

Svar: B

Motivering: I detta fall förväntas Action< Animal>, så du kan använda Animal där Tiger förväntas.

22
Q
Func<Animal, Tiger> convertToTiger;
Func<Tiger, Animal> convertToAnimal = (Tiger tiger) => new Animal();

convertToTiger = convertToAnimal;
  • Vilket påstående bäst beskriver situationen i ovanstående kodsnutt?

A) Koden kommer att orsaka ett kompileringsfel eftersom det är en kontravariant situation, inte kovariant.

B) Koden kommer att kompilera eftersom Func-delegaten är kovariant i sin returtyp.

C) Koden kommer att kompilera, men ett körtidsundantag kommer att uppstå vid försök att köra convertToTiger.

A

Svar: A

Motivering: I detta fall försöker du tilldela en Func< Tiger, Animal> till en Func< Animal, Tiger>, vilket inte är en kovariant situation för resultattypen. Det kommer att orsaka ett kompileringsfel, vilket är vad du har noterat.

23
Q
interface IWrapper<out T>
{
    T Value { get; }
}

class Wrapper<T> : IWrapper<T>
{
    public Wrapper(T value) { Value = value; }
    public T Value { get; private set; }
}

var stringWrapper = new Wrapper<string>("test");
IWrapper<object> objectWrapper = stringWrapper;
Console.WriteLine(objectWrapper.Value.GetType().Name);

Fråga: Vad skriver ovanstående kod ut?

A) Wrapper
B) String
C) Object

A

Svar: B

24
Q
public class ClassA { /* ... */ }
public class ClassB : ClassA { /* ... */ }

Action<ClassA> actionA = (obj) => Console.WriteLine(obj.GetType().Name);
Action<ClassB> actionB = actionA;  

Fråga: Kompilerar koden ovan korrekt?

A) Ja, eftersom Action-delegaten är kontravariant i dess parametertyp.
B) Nej, eftersom Action-delegaten är kontravariant och inte tillåter denna typ av typomvandling.
C) Ja, men ett undantag kommer att kastas vid körning när derivedAction kallas.

A

Svar: B

Motivering:
I det här fallet är Action< T> en kontravariant delegat. Kontravarians innebär att du kan tilldela en mer generell (bas)typ till en mer specifik (derivat)typ. Men i ditt exempel försöker du göra motsatsen, det vill säga tilldela en Action< ClassA> till en Action< ClassB>, vilket inte är tillåtet för en kontravariant delegat. Så koden kommer inte att kompilera.

25
Q
interface IRepository<in T>
{
    void Save(\_\_\_\_\_\_ entity);
}

class Repository<T> : IRepository<T>
{
    public void Save(T entity) { /* save logic */ }
}

Fråga: Vilken typ bör ersätta de tomma understrykningarna för att säkerställa att gränssnittet och klassen följer kontravariansprinciperna korrekt?

A) T
B) Object
C) IRepository

A

Svar: A

26
Q

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?

Apple : Fruit
Fruit : Edible

a) I<Apple> : I<Fruit>

b) I<Fruit> : I<Apple>

c) I<Apple> : I<Edible>
A

Svar:
a) I< Apple> : I< Fruit>
c) I< Apple> : I< Edible>

27
Q

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?

Apple:Fruit
Fruit:Edible

a) I<Fruit> : I<Apple>

b) I<Apple> : I<Edible>

c) I<Edible> : I<Fruit>
A

Svar: b) I< Apple> : I< Edible>

28
Q

Anta att följande hierarki gäller: Banana är en subtyp av Fruit, och Fruit är en subtyp av Edible. Dessutom är T kontravariant i I< T>. Vilka av följande påståenden är sanna?

Banana: Fruit
Fruit: Edible

a) I<Banana> : I<Fruit>

b) I<Fruit> : I<Banana>

c) I<Banana> : I<Edible>
A

Svar:
b) I< Fruit> : I< Banana>

29
Q
class A { }
class B : A { }

class ASeq
{
    public virtual A GetNext()
        => new A(); // Placeholder implementation.
}

class BSeq : ASeq
{
    public override B GetNext()
        => new B(); // Placeholder implementation.
}

Vad beskriver bäst kovarians i sammanhanget med klasserna A och B samt metoderna GetNext?

a) Kovarians gör att du kan använda BSequence i stället för ASequence eftersom B är en subtyp av A.

b) Kovarians gör att du kan använda ASequence i stället för BSequence eftersom A är en överordnad typ av B.

c) Kovarians gör ingen skillnad i detta sammanhang; du kan inte byta ut ASequence och BSequence.

A

a) Kovarians gör att du kan använda BSequence i stället för ASequence eftersom B är en subtyp av A.

30
Q
class B { }
class A : B
{
    Action<B> bPrinter;
    Action<A> aPrinter;

    public A()
    {
        bPrinter = (B x) => Console.WriteLine("meddelande");
        aPrinter = bPrinter;
    }
}

Fråga: Kompilerar koden ovan korrekt?

  1. Ja koden kompilerar.
  2. Nej.
  3. Det blir exeption men den kompilerar.
A

Rättsvar: 1.

31
Q
public class Person { }
public class Employee : Person { }
public class Manager : Employee { }

var personObject = new Person();
var employeeObject = new Employee();
var managerObject = new Manager();

personObject = employeeObject;
personObject = managerObject;

Vad är detta för varians?

  1. Kovarians
  2. Kontravarians
  3. inget av de andra alternativen
A

Svar: Kovarians.

Motivering:

I kovarians tillåts en typ att bli mer specificerad i en undertyp. I ditt exempel tilldelas personObject först employeeObject och sedan managerObject. Eftersom Employee ärver från Person och Manager ärver från Employee, kan du tilldela en instans av Manager till en variabel av typen Person.

32
Q
public class Person { }
public class Employee : Person { }
public class Manager : Person { }
Person[] people = new Employee[5];
people[0] = new Manager();

Vad är detta för varians?

  1. Kovarians
  2. Kontravarians
  3. inget av de andra alternativen
A

Svar: 1. Kovarians.

Motivering:
I kovarians tillåts en typ att bli mer specificerad i en undertyp. I detta fall skapar du en array av Person, men tilldelar den en instans av Employee[], och sedan tilldelar du en Manager till en position i arrayen. Eftersom Manager är en subtyp av Person fungerar detta i en kovariant kontext.

33
Q
public class Person { }
public class Employee : Person { }
public class Manager : Employee { }

var personObject = new Person();
var employeeObject = new Employee();
var managerObject = new Manager();

Person[] people = { new Person() };
Employee[] employees = people;

Vad är detta för varians?

  1. Kovarians
  2. Kontravarians
  3. inget av de andra alternativen
A

Svar: 2. Kontravarians.

Motivering: I kontravarians tillåts en typ att bli mindre specificerad i en undertyp. I ditt exempel försöker du tilldela en Person[] till en Employee[], vilket inte är tillåtet.