Tenta 2023 Flashcards

1
Q
  • Vad är kärnidén bakom beroendeinjektion?

Välj ett alternativ:

  1. Att fokusera på skapandet av objekt istället för dess användande.
  2. Att kombinera ett objekts skapande med dess användning.
  3. Att separera ett objekts skapande från dess användning
A
  1. Att separera ett objekts skapande från dess användning.

Motivering:
- Kärnidén bakom beroendeinjektion är att separera ett objekts skapande från dess användning. Genom att använda beroendeinjektion kan vi skapa objekt oberoende av de specifika detaljerna för hur de används, vilket gör vår kod mer flexibel och underlättar testning och underhåll.

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

Vilken typ av beroendeinjektion används i koden?

 1. interface IJumpBehavior
 2. {
 3.     void Execute();
 4. }
 5. 
 6. class Player
 7. {
 8.     IJumpBehavior jumpBehavior;
 9. 
10.     public Player(IJumpBehavior jumpBehavior)
11.         => this.jumpBehavior = jumpBehavior;
12. 
13.     public void SetJumpBehavior(IJumpBehavior jumpBehavior)
14.         => this.jumpBehavior = jumpBehavior;
15. 
16.     public void Jump()
17.         => jumpBehavior.Execute();
18. }
  • Välj ett alternativ:
  1. Konstruktor-injektion och Egenskaps-injektion.
  2. Konstruktor-injektion och Metod-injektion.
  3. Metod-injektion och Egenskaps-injektion.
A
  1. Konstruktor-injektion och Metod-injektion.

Motivering:

  • I koden används konstruktor-injektion för att tillhandahålla IJumpBehavior-beroendet vid skapandet av en instans av Player. Konstruktorn tar jumpBehavior som en parameter och sätter det när en ny Player skapas.
  • Metoden Jump() i koden använder en form av metod-injektion. Beroendet jumpBehavior injiceras i Jump()-metoden och används där direkt för att utföra Execute()
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

I termer av Strategy Pattern, vilken roll spelar typen IWeaponBehavior?

 1. interface IWeaponBehavior
 2. {
 3.     void Attack();
 4. }
 5. 
 6. class Player
 7. {
 8.     IWeaponBehavior behavior;
 9. 
10.     public Player(IWeaponBehavior behavior)
11.         => this.behavior = behavior;
12. 
13.     public void Attack()
14.         => behavior.Attack();
15. }
  • Välj ett alternativ:
  1. Konkret strategi
  2. Kontext
  3. Abstrakt strategi
A
  1. Abstrakt strategi

Motivering: Typen IWeaponBehavior representerar den abstrakta strategin i Strategy Pattern. Den definierar det gemensamma gränssnittet för alla konkreta strategier som implementerar olika vapenbeteenden (Attack). Genom att använda en abstrakt strategi tillåter mönstret att dynamiskt byta ut och bygga olika beteenden vid körning, vilket ökar flexibiliteten och möjliggör en enkel utökning av systemet genom att lägga till nya vapenbeteenden.

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

Vad blir resultatet av att köra följande program?

 1. List<IA> list = new List<IA>() { new A(), new A(), new B() };
 2. 
 3. foreach (IA a in list)
 4. {
 5.     C c = new C(a);
 6.     c.Execute();
 7. }
 8. 
 9. 
10. interface IA
11. {
12.     void Run();
13. }
14. 
15. class A : IA
16. {
17.     public void Run() => Console.Write("x");
18. }
19. 
20. class B : IA
21. {
22.     public void Run() => Console.Write("y");
23. }
24. 
25. class C
26. {
27.     private IA a;
28. 
29.     public C(IA a)
30.         => this.a = a;
31. 
32.     public void Execute()
33.         => a.Run();
34. }
  • Välj ett alternativ:
  1. Koden kompilerar inte.
  2. yxx
  3. xxy
A
  1. xxy

Motivering: När listan List< IA> skapas, fylls den med två instanser av A och en instans av B. Sedan genomgår en foreach-loop varje element i listan och skapar en ny instans av C med varje IA-objekt från listan och anropar sedan Execute-metoden. Eftersom C-konstruktorn tar en IA-parameter, kan den ta både A och B.

Så, när Execute-metoden anropas, utförs Run-metoden för varje IA-objekt. Eftersom Run-metoden för A skriver ut “x” och för B skriver ut “y”, blir resultatet “xxy”.

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

Vad ska ____ ersättas med för att programmet ska generera det angivna resultatet?

 1. A a = new A(new B());
 2. a.Execute();
 3. 
 4. interface IStrategy
 5. {
 6.     void Execute();
 7. }
 8. 
 9. class B : IStrategy
10. {
11.     public void Execute()
12.         => Console.WriteLine("B");
13. }
14. 
15. class A
16. {
17.     private IStrategy s;
18. 
19.     public A(IStrategy s)
20.         => this.s = s;
21. 
22.     public void Execute()
23.         => _ _ _ _
24. }
  • Välj ett alternativ:
  1. this.Execute();
  2. s.Execute();
  3. a.Execute();
A
  1. s.Execute();

Motivering: För att korrekt anropa Execute-metoden från den instans som är lagrad i IStrategy-fältet s i klassen A, bör alternativ 2. s.Execute(); användas. Eftersom A har en komposition med IStrategy (tillhandahållen vid instansiering) kan Execute-metoden för den specifika strategin, som i detta fall är en instans av B, kallas korrekt genom att använda s.Execute();

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

Vilket påstående beskriver bäst varför komposition föredras över arv?

  • Välj ett alternativ:
  1. Arv ger oss endast möjligheten att återanvända kod ifrån en superklass i dess subklasser.
  2. Komposition möjliggör återanvändning av kod ifrån en superklass i dess subklasser.
  3. Komposition ger oss möjligheten att återanvända kod ifrån en superklass i dess subklasser.
A
  1. Arv ger oss endast möjligheten att återanvända kod ifrån en superklass i dess subklasser.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Vilket påstående stämmer?

 1. class A
 2. {
 3.     B b;
 4.     public A(B b) => this.b = b;
 5. }
 6. 
 7. class B : A
 8. {
 9.     public B() : base(null) { }
10. }
  • Välj ett alternativ:
  1. A is-a B.
  2. A has-a B.
  3. B has-a A.
A
  1. A has-a B.

Motivering: I detta fall har klassen A en medlem av typen B med namnet b

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

Vad blir resultatet av att köra följande program?

 1. Y y = new Y2(new X1());
 2. Console.WriteLine(y.GetY());
 3. 
 4. interface IX
 5. {
 6.     string GetX();
 7. }
 8. 
 9. class X1 : IX
10. {
11.     public string GetX() => "Green";
12. }
13. 
14. class X2 : IX
15. {
16.     public string GetX() => "Blue";
17. }
18. 
19. abstract class Y
20. {
21.     protected IX x;
22.     public Y(IX x) => this.x = x;
23.     public abstract string GetY();
24. }
25. 
26. class Y1 : Y
27. {
28.     public Y1(IX x) : base(x) { }
29.     public override string GetY()
30.         => x.GetX() + " Rectangle";
31. }
32. 
33. class Y2 : Y
34. {
35.     public Y2(IX x) : base(x) { }
36.     public override string GetY()
37.         => x.GetX() + " Circle";
38. }
  • Välj ett alternativ:
  1. Green Rectangle
  2. Green Circle
  3. Blue Circle
A
  1. Green Circle

Motivering:

  • Y y = new Y2(new X1()); skapar en instans av Y2 och skickar en instans av X1 som parameter.
  • Inom Y2-klassen anropas x.GetX() där x är en instans av X1. Detta returnerar “Green”.
  • Sedan läggs “ Circle” till och resultatet som skrivs ut är “Green Circle”.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Vad ska ____ ersättas med för att programmet ska generera det angivna resultatet?

 1. AL x = new CL(new R());
 2. Console.WriteLine(x.Exec());
 3. 
 4. interface IR
 5. {
 6.     string Exec();
 7. }
 8. 
 9. class R : IR
10. {
11.     public string Exec() => "Concrete Right";
12. }
13. 
14. abstract class AL
15. {
16.     protected IR r;
17.     public AL(IR r) => this.r = r;
18.     public virtual string Exec()
19.         => _ _ _ _
20. }
21. 
22. class CL : AL
23. {
24.     public CL(IR r) : base(r) { }
25. }
  • Välj ett alternativ:

r.Exec();

this.r;

this.Exec();

A

r.Exec();

Motivering:
För att anropa Exec()-metoden från den instans av IR som är lagrad i r-fältet i klassen AL, bör r.Exec(); användas i rad 19. Detta möjliggör korrekt körning av Exec() för den specifika implementeringen av IR, som i detta fall är en instans av R.

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

Vad representerar T1 och T2 i Pair< T1,T2> i koden nedan?

 1. class Pair<T1, T2>
 2. {
 3.     public T1 Item1 { get; private set; }
 4.     public T2 Item2 { get; private set; }
 5. 
 6.     public Pair(T1 item1, T2 item2)
 7.     {
 8.         Item1 = item1;
 9.         Item2 = item2;
10.     }
11. }
 
  • Välj ett alternativ:
  1. Specifika datatyper som int eller string.
  2. Typ-parametrar som kan ersättas av valfri datatyp när den generiska typen konstrueras.
  3. Typ-argument som används istället för T1 och T2.
A
  1. Typ-parametrar som kan ersättas av valfri datatyp när den generiska typen konstrueras.

Motivering:
I koden representerar T1 och T2 generiska typ-parametrar, vilket innebär att de kan ersättas av valfria datatyper när en instans av den generiska klassen skapas. Det möjliggör skapandet av en flexibel och återanvändbar klass som kan hantera olika datatyper.

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

Kompilerar följande program?

 1. Pair<int, string> pair = new Pair<int, string>("hello", 5);
 2. 
 3. class Pair<T1, T2>
 4. {
 5.     public T1 Item1 { get; set; }
 6.     public T2 Item2 { get; set; }
 7. 
 8.     public Pair(T1 item1, T2 item2)
 9.     {
10.         Item1 = item1;
11.         Item2 = item2;
12.     }
13. }
  • Välj ett alternativ:
  1. Nej, p.g.a. syntax-fel.
  2. Nej, p.g.a. typ-fel.
  3. Ja.
A
  1. Nej, p.g.a. typ-fel.

Motivering:
Ordningen för Pair är < int, string>.

Vi skickar dock in (“hello”, 5) vilket kommer orsaka typ-fel då string:en och int:en ligger i omvänd ordning.

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

Kompilerar följande program?

 1. Apple apple = new Apple();
 2. Box<Fruit> box = new Box<Fruit>(apple);
 3. string variety = box.Item.Variety;
 4. 
 5. class Fruit
 6. {
 7.     public bool IsRipe { get; set; }
 8. }
 9. 
10. class Apple : Fruit
11. {
12.     public string Variety { get; set; }
13. }
14. 
15. class Box<T>
16. {
17.     public T Item { get; private set; }
18.     public Box(T item) => Item = item;
19. }
 
  • Välj ett alternativ:
  1. Nej, eftersom Box inte stödjer objekt av typ Apple.
  2. Nej, eftersom variabeln box och det objekt den pekar på är av typen Box< Fruit> och inte Box< Apple>.
  3. Ja.
A
  1. Nej, eftersom variabeln box och det objekt den pekar på är av typen Box< Fruit> och inte Box< Apple>.

Motivering:
Box< Fruit> och Box< Apple> är olika typer, även om Apple ärver från Fruit. I C# är generiska typer inte covarianta, vilket betyder att du inte kan använda en Box< Apple> där en Box< Fruit> förväntas.

  • Så, felet ligger i att box är av typen Box< Fruit>, och den försöker referera till en instans av Box< Apple>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

denna var fel

A

denna var fel

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

Vad ska ____ ersättas med för att programmet ska generera det angivna resultatet?

 1. Calculator calc = new Calculator();
 2. Console.WriteLine(calc.Add(10, 20));
 3. 
 4. interface ICalculator<T>
 5. {
 6.     T Add(T a, T b);
 7. }
 8. 
 9. class Calculator : ICalculator<int>
10. {
11.     _ _ _ _
12. }
30.
  • Välj ett alternativ:
  1. public int Add(T a, T b) => a + b;
  2. public int Add(int a, int b) => a + b;
  3. public T Add(T a, T b) => a + b;
A
  1. public int Add(int a, int b) => a + b;

Motivering: Eftersom Calculator implementerar ICalculator< int>, behöver metoden Add ha samma signatur som definierats i gränssnittet ICalculator< T>. I detta fall är T ersatt med int, så metoden måste acceptera två int-parametrar och returnera en int.

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

Kompilerar följande program?

1. class Factory<T> where T : class
2. {
3.     public T CreateItem() => new T();
4. }

Välj ett alternativ:

  1. Ja, eftersom alla typer har en parameterlös konstruktor.
  2. Ja, eftersom alla klasser har en parameterlös konstruktor.
  3. Nej, eftersom T inte nödvändigtvis har en parameterlös konstruktor.
A
  1. Nej, eftersom T inte nödvändigtvis har en parameterlös konstruktor.

Motivering: När du försöker skapa en instans av T med new T() antar detta att T har en parameterlös konstruktor, vilket inte är garanterat när du använder en generisk typparameter. Det är därför kompilatorn inte kommer att tillåta detta om inte T är begränsat med new()-begränsningen för att indikera att T måste ha en parameterlös konstruktor.

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

Vad är det huvudsakliga syftet med att använda delegater?

  • Välj ett alternativ:
  1. Att behandla metoder som objekt.
  2. Att behandla objekt som metoder.
  3. Att undvika lambda-uttryck.
A
  1. Att behandla metoder som objekt.
17
Q

Vilket påstående stämmer?

delegate void A (int value);
 
  • Välj ett alternativ:
  1. A är en typ vars värden är metoder som tar en int och inte returnerar något.
  2. A är ett värde som tar en int och inte returnerar något.
  3. A är en metod som tar emot en int och inte returnerar något.
A
  1. A är en typ vars värden är metoder som tar en int och inte returnerar något.

Motivering:
delegate används för att deklarera en typ som representerar metoder med en viss signatur.

18
Q

Kompilerar följande program?

1. StringFactory f = MakeLine();
2. string MakeLine () => "==========";
3. delegate string StringFactory ();
 
  • Välj ett alternativ:
  1. Nej, eftersom den lokala funktionen MakeLine inte har en typ som är kompatibel med StringFactory.
  2. Ja.
  3. Nej, eftersom vi försöker lagra resultatet av att köra MakeLine() i f.
A
  1. Nej, eftersom vi försöker lagra resultatet av att köra MakeLine() i f.

Motivering: En lokal funktion (MakeLine) måste ha en explicit returntyp om den används som en delegat. I det här fallet har MakeLine en implicit string-returntyp = kompilerar inte.

19
Q

Vad ska ____ ersättas med för att programmet ska kompilera?

_ _ _ _ whichIsGreater = (x, y) => x > y ? "First" : "Second";
 
  • Välj ett alternativ:
  1. Action < int, int, string >
  2. Func < int, string >
  3. Func < int, double, string >
A
  1. Func < int, double, string >

Motivering:
Eftersom whichIsGreater returnerar en string och tar två int som parametrar, kan denna användas:
Func< int, double, string>.

20
Q

Vad blir resultatet av att köra följande program?

 1. Podcast podcast = new Podcast() { Title = "Tech Talks" };
 2. 
 3. Listener listenerA = new Listener() { Name = "Alice" };
 4. Listener listenerB = new Listener() { Name = "Bob" };
 5. 
 6. podcast.Subscribe(listenerA);
 7. podcast.Subscribe(listenerB);
 8. podcast.ReleaseNewEpisode();
 9. podcast.Subscribe(listenerB);
10. podcast.ReleaseNewEpisode();
11. 
12. class Podcast
13. {
14.     public string Title { get; init; }
15. 
16.     private List<ISubscriber> subs = new List<ISubscriber>();
17. 
18.     public void Subscribe(ISubscriber subscriber)
19.         => subs.Add(subscriber);
20. 
21.     public void Unsubscribe(ISubscriber subscriber)
22.         => subs.Remove(subscriber);
23. 
24.     public void ReleaseNewEpisode()
25.     {
26.         foreach (var sub in subs)
27.             sub.Update(this);
28.     }
29. }
30. 
31. interface ISubscriber
32. {
33.     void Update(Podcast podcast);
34. }
35. 
36. class Listener : ISubscriber
37. {
38.     public string Name { get; init; }
39. 
40.     public void Update(Podcast podcast)
41.         => Console.Write(Name + " ");
42. }
 

Välj ett alternativ:

  1. Alice Bob
  2. Alice Bob Alice
  3. Alice Bob Alice Bob Bob
A
  1. Alice Bob Alice Bob Bob

Motivering:

  • Podcasten “Tech Talks” skapas.
  • Två lyssnare, Alice och Bob, prenumererar på podcasten.
  • En ny episod släpps, och båda lyssnarna får en uppdatering (Update) vilket resulterar i “Alice Bob”.
  • Bob prenumererar på podcasten igen.
  • En ny episod släpps, och lyssnarna är nu (Alice Bob Bob) får uppdateringar, så resultatet blir “Alice Bob Alice Bob Bob”.
21
Q

Vad blir resultatet av att köra följande program?

int n = 0;

void Inc(object sender, EpisodeEventArgs e) => n++;
void Dec(object sender, EpisodeEventArgs e) => n--;

Podcast podcast = new Podcast();

podcast.PublishEpisode("E1");
podcast.EpisodeRemoved += Inc;
podcast.EpisodeRemoved += Inc;
podcast.EpisodePublished += Dec;
podcast.PublishEpisode("E2");
podcast.EpisodePublished += Inc;
podcast.PublishEpisode("E3");
podcast.RemoveEpisode("E1");
podcast.EpisodePublished -= Dec;
podcast.PublishEpisode("E4");

Console.WriteLine(n);

class Podcast
{
    public event EventHandler<EpisodeEventArgs> EpisodePublished;
    public event EventHandler<EpisodeEventArgs> EpisodeRemoved;

    public void PublishEpisode(string name)
        => EpisodePublished?.Invoke(this, new EpisodeEventArgs(name));

    public void RemoveEpisode(string name)
        => EpisodeRemoved?.Invoke(this, new EpisodeEventArgs(name));
}

class EpisodeEventArgs : EventArgs
{
    public string Name { get; private set; }
    public EpisodeEventArgs(string name) => Name = name;
}

 
  • Välj ett alternativ:
  1. 3
  2. 2
  3. 1
A

Svar: alt 2.

Motivering:

  1. n initialiseras till 0.
  2. Två metoder (Inc och Dec) skapas för att öka och minska värdet av n.
  3. En instans av Podcast skapas.
  4. En episod (“E1”) publiceras, men ingen händelse prenumereras på detta steg.
  5. Två händelser prenumereras på händelsen EpisodeRemoved, vilket innebär att Inc kommer att kallas två gånger för varje borttagen episod.
  6. En händelse prenumereras på EpisodePublished, och Dec kommer att kallas varje gång en episod publiceras.
  7. En episod (“E2”) publiceras, vilket resulterar i att Dec kallas och n minskas med 1.
    (n = -1)
  8. En händelse prenumereras på EpisodePublished, och både Inc och Dec kommer att kallas varje gång en episod publiceras. Alltså kommer inget hända med n.
  9. En episod (“E3”) publiceras, vilket resulterar i att Inc kallas och n ökas med 0.
    (n = -1)
  10. En episod (“E1”) tas bort, vilket resulterar i att Inc kallas två gånger eftersom två prenumerationer. n ökas med 2.
    (n= 1)
  11. En händelseprenumeration på EpisodeRemoved tas bort, så nu kommer n bara öka med +1 ifall den kallas.
  12. En episod (“E4”) publiceras, EpisodeRemoved premurationen kommer nu göra att n ökas med +1.
    (n= 2)
  13. Console.WriteLine(n) skrivs ut, vilket visar värdet av n (2) efter de olika händelserna.
22
Q

Vad är det huvudsakliga syftet med Iterator pattern?

Välj ett alternativ:

  1. Att erbjuda ett sätt att exponera den underliggande representationen för olika itererbara objekt.
  2. Att erbjuda ett sätt att komma åt element i ett itererbart objekt sekventiellt utan att avslöja dess underliggande representation.
  3. Att definiera metoder för att lägga till, ta bort och uppdatera element i en kollektion.
A
  1. Att erbjuda ett sätt att komma åt element i ett itererbart objekt sekventiellt utan att avslöja dess underliggande representation.
23
Q

Vilket syfte har metoden MoveNext i gränssnittet IIterator< T>?

1. interface IIterator<T>
2. {
3.     T Current { get; }
4.     bool MoveNext();
5.     void Reset();
6. }

Välj ett alternativ:

  1. Den flyttar pekaren till nästa element och returnerar värdet av detta element.
  2. Den flyttar pekaren till nästa element om det finns och returnerar en boolean som representerar huruvida det gick att flytta eller ej.
  3. Den kontrollerar endast om det finns fler element att iterera över i kollektionen.
A
  1. Den flyttar pekaren till nästa element om det finns och returnerar en boolean som representerar huruvida det gick att flytta eller ej.
24
Q

Kommer följande program att fastna i en evig loop?

 1. IEnumerable<int> NaturalNumbers()
 2. {
 3.     int i = 0;
 4.     while (true)
 5.         yield return i++;
 6. }
 7. 
 8. IEnumerator<int> enumerator = NaturalNumbers().GetEnumerator();
 9. 
10. while (enumerator.MoveNext())
11. {
12.     Console.Write(enumerator.Current);
13.     if (enumerator.Current >= 5) break;
14. }
 
  • Välj ett alternativ:
  1. Nej.
  2. Ja, programmet fastnar i den undre while-loop:en för evigt.
  3. Ja, programmet fastnar i den övre while-loop:en för evigt.
A
  1. Nej.

Motivering: Det kommer att skriva ut de naturliga talen från 0 till 5 och sedan avsluta. Detta beror på att yield return i++; genererar talen i en följd, och när enumerator.Current når värdet 5, kommer break; att avsluta loopen.

25
Q

Vilket påstående beskriver bäst Liskov Substitution Principle?

  • Välj ett alternativ:
  1. En supertyp måste kunna användas på alla ställen där en subtyp förväntas utan att oväntat beteende introduceras.
  2. En subtyp måste göra samma sak som sin supertyp eller mer.
  3. En subtyp måste kunna användas på alla ställen där dess supertyp förväntas utan att oväntat beteende introduceras.
A
  1. En subtyp måste kunna användas på alla ställen där dess supertyp förväntas utan att oväntat beteende introduceras.
26
Q
class A
{
    protected int X, Y;
    public virtual void SetValues(int x, int y)
    {
        if (x < 0 || y < 0)
        {
            X = x;
            Y = y;
        }
    }
}

class B : A
{
    public override void SetValues(int x, int y)
    {
        if (x < 10 || y < 10)
            throw new ArgumentException();
        
        X = x;
        Y = y;
    }
}
  • Välj ett alternativ:
  1. Koden bryter mot Liskov Substitution Principle eftersom post-conditions är svagare i subklassen.
  2. Koden bryter mot Liskov Substitution Principle eftersom pre-conditions är starkare i subklassen.
  3. Koden följer Liskov Substitution Principle eftersom pre-conditions är svagare i subklassen.
A
  1. Koden bryter mot Liskov Substitution Principle eftersom pre-conditions är starkare i subklassen.

Motivering: Liskov Substitution Principle (LSP) säger att en instans av en superklass ska kunna ersättas med en instans av en subklass utan att påverka programmets korrekthet. I det här fallet har preconditions (villkor för att anropa metoden) förändrats i subklassen B eftersom den kastar ett undantag (ArgumentException) om x eller y är mindre än 10. Detta innebär att den subklassen har en starkare pre-condition än superklassen, vilket bryter mot Liskov Substitution Principle.

27
Q

Kompilerar följande kod?

1. void ProcessFruit(Fruit fruit)
2.     => Console.WriteLine("Processing the fruit.");
3. 
4. AppleProcessor processor = ProcessFruit;
5. 
6. class Fruit { }
7. class Apple : Fruit { }
8. 
9. delegate void AppleProcessor(Apple apple);
  • Välj ett alternativ:
  1. Ja, eftersom delegater är kovarianta i input.
  2. Nej, eftersom delegater är invarianta utan nyckelorden in och out.
  3. Ja, eftersom delegater är kontravarianta i input.
A
  1. Ja, eftersom delegater är kontravarianta i input.

Motivering: Delegater i C# är faktiskt kontravarianta i sina parametrar.

I detta fall kan du använda en AppleProcessor-delegat för att peka på en metod som tar emot en mer allmän typ, t.ex. Fruit.

  • Så, ProcessFruit-metoden som tar emot en Fruit-parameter kan tilldelas till en AppleProcessor-delegat. Detta är möjligt eftersom AppleProcessor är kontravariant i inputtypen.
28
Q

Kompilerar följande program?

 1. AppleTree appleTree = new AppleTree();
 2. Apple apple = appleTree.PickFruit();
 3. FruitTree fruitTree = appleTree;
 4. 
 5. class Fruit { }
 6. 
 7. class Apple : Fruit { }
 8. 
 9. class FruitTree
10. {
11.     public virtual Fruit PickFruit() => new Fruit();
12. }
13. 
14. class AppleTree : FruitTree
15. {
16.     public override Apple PickFruit() => new Apple();
17. }
 
  • Välj ett alternativ:
  1. Nej, eftersom C# inte stödjer varians i returtyper i klasser.
  2. Ja, eftersom C# stödjer kovarianta returtyper i klasser.
  3. Ja, eftersom C# stödjer kontravarianta returtyper i klasser.
A
  1. Ja, eftersom C# stödjer kovarianta returtyper i klasser.

Motivering: I C# stöds kovarianta returtyper i överlagrade metoder och egenskaper, vilket innebär att du kan ha en mer specifik returtyp i en avledad klass jämfört med returtypen i den överordnade klassen.

  • I detta fall är PickFruit-metoden överskuggad i AppleTree och har en mer specifik returtyp (Apple) jämfört med den överordnade klassens returtyp (Fruit).
29
Q

Vilket påstående stämmer?

 1. class A
 2. {
 3.     protected int X, Y;
 4.     public virtual void SetValues(int x, int y)
 5.     {
 6.         if (x < 0 || y < 0)
 7.             throw new ArgumentException();
 8.         X = x;
 9.         Y = y;
10.     }
11. }
12. 
13. class B : A
14. {
15.     public override void SetValues(int x, int y)
16.     {
17.         if (x < 10 || y < 10)
18.             throw new ArgumentException();
19.         X = x;
10.         Y = y;
11.     }
12. }

Välj ett alternativ:

  1. Koden bryter mot Liskov Substitution Principle eftersom post-conditions är svagare i subklassen.
  2. Koden bryter mot Liskov Substitution Principle eftersom pre-conditions är starkare i subklassen.
  3. Koden följer Liskov Substitution Principle eftersom pre-conditions är svagare i subklassen.
A
  1. Koden bryter mot Liskov Substitution Principle eftersom pre-conditions är starkare i subklassen.

Motivering: Liskov Substitution Principle (LSP) säger att objekt av en överordnad klass ska kunna ersättas med objekt av en underordnad klass utan att påverka programmets korrekthet.

Så: Ett sätt att bryta mot LSP är att införa starkare förutsättningar (pre-conditions) i en subklass. I detta fall har subklassen B hårdare (mer restriktiva) förutsättningar i SetValues-metoden jämfört med förälderklassen A.

30
Q

Vilket påstående stämmer?

1. F<B> bf = () => new B();
2. F<A> af = bf;
3. 
4. delegate T F<out T>();
5. 
6. class A { }
7. class B : A { }
  • Välj ett alternativ:
  1. Detta är ett exempel på kontravarians som kompilerar.
  2. Detta är ett exempel på kovarians som kompilerar.
  3. Detta är ett exempel på kovarians som inte kompilerar.
A
  1. Detta är ett exempel på kovarians som kompilerar.

Motivering: I detta exempel används out-nyckelordet i definitionen av delegaten F, vilket gör den kovariant. Med kovarians kan du konvertera från en mer specifik typ (till exempel F< B>) till en mer generell typ (F< A>), vilket är vad som händer i rad 2 där en F< B> delegerad tilldelas en F< A> variabel.

En påse av äpple är också en påse av frukt!.

31
Q

Kompilerar följande program?

1. interface ITest<out T>
2. {
3.     T Method1();
4.     void Method2(T value);
5. }
  • Välj ett alternativ:
  1. Ja, eftersom T är kovariant.
  2. Nej, eftersom en kovariant typ-parameter inte får användas som någon metods retur-typ.
  3. Nej, eftersom en kovariant typ-parameter inte får förekomma i någon metods parameter-lista.
A
  1. Nej, eftersom en kovariant typ-parameter inte får förekomma i någon metods parameter-lista.

Motivering: Eftersom T är markerad med out-nyckelordet, vilket gör den kovariant, kan den bara användas som en returtyp i en metod och inte som en parameter i en metod.