Bird
Raised Fist0
C Sharp (C#)programming~20 mins

Covariance with out keyword in C Sharp (C#) - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Covariance Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of covariance with interface using out keyword
What is the output of this C# code using covariance with the out keyword in interfaces?
C Sharp (C#)
interface IProducer<out T> { T Produce(); }
class Animal { public override string ToString() => "Animal"; }
class Dog : Animal { public override string ToString() => "Dog"; }
class DogProducer : IProducer<Dog> {
    public Dog Produce() => new Dog();
}

class Program {
    static void Main() {
        IProducer<Dog> dogProducer = new DogProducer();
        IProducer<Animal> animalProducer = dogProducer; // Covariance allows this
        Animal animal = animalProducer.Produce();
        System.Console.WriteLine(animal);
    }
}
ARuntime exception
BAnimal
CCompilation error due to covariance
DDog
Attempts:
2 left
💡 Hint
Remember that covariance with out allows assignment from more derived to less derived types.
❓ Predict Output
intermediate
2:00remaining
Covariance with delegates and out keyword
What will this C# program print when using covariance with delegates and the out keyword?
C Sharp (C#)
delegate T Factory<out T>();
class Fruit { public override string ToString() => "Fruit"; }
class Apple : Fruit { public override string ToString() => "Apple"; }

class Program {
    static Apple CreateApple() => new Apple();
    static void Main() {
        Factory<Apple> appleFactory = CreateApple;
        Factory<Fruit> fruitFactory = appleFactory; // Covariance
        System.Console.WriteLine(fruitFactory());
    }
}
AApple
BFruit
CCompilation error due to delegate variance
DNullReferenceException at runtime
Attempts:
2 left
💡 Hint
Delegates with out type parameters support covariance.
🔧 Debug
advanced
2:30remaining
Why does this covariance assignment fail?
Consider this code snippet. Why does the assignment cause a compilation error despite using out keyword?
C Sharp (C#)
interface IContainer<out T> { T GetItem(); void AddItem(T item); }
class Container<T> : IContainer<T> {
    private T item;
    public T GetItem() => item;
    public void AddItem(T item) { this.item = item; }
}

class Program {
    static void Main() {
        IContainer<string> stringContainer = new Container<string>();
        IContainer<object> objectContainer = stringContainer; // Error here
    }
}
ABecause <code>IContainer&lt;out T&gt;</code> cannot have input parameters like <code>AddItem(T item)</code>.
BBecause <code>string</code> cannot be assigned to <code>object</code>.
CBecause covariance only works with classes, not interfaces.
DBecause <code>Container&lt;T&gt;</code> does not implement <code>IContainer&lt;T&gt;</code> correctly.
Attempts:
2 left
💡 Hint
Check the variance rules for out type parameters and method input parameters.
📝 Syntax
advanced
2:00remaining
Identify the syntax error with covariance and out keyword
Which option contains the syntax error when declaring a covariant interface with the out keyword?
C Sharp (C#)
interface IReadOnlyList<out T> {
    T Get(int index);
    void Add(T item);
}
AThe method <code>Get(int index)</code> cannot return <code>T</code> in a covariant interface.
BThe interface cannot have a method <code>Add(T item)</code> because <code>T</code> is covariant (out).
CThe <code>out</code> keyword must be placed after the interface name, not before <code>T</code>.
DThe interface must be declared as <code>interface IReadOnlyList&lt;in T&gt;</code> for covariance.
Attempts:
2 left
💡 Hint
Covariant type parameters can only be used as return types, not input parameters.
🚀 Application
expert
3:00remaining
Using covariance with LINQ and out keyword
Given the following code, what is the output when using covariance with out keyword and LINQ?
C Sharp (C#)
using System;
using System.Collections.Generic;
using System.Linq;

interface ISource<out T> {
    IEnumerable<T> GetItems();
}

class NumberSource : ISource<int> {
    public IEnumerable<int> GetItems() => new List<int> {1, 2, 3};
}

class Program {
    static void Main() {
        ISource<int> intSource = new NumberSource();
        ISource<object> objSource = intSource; // Covariance
        foreach (var item in objSource.GetItems().Select(x => x.ToString())) {
            Console.Write(item + " ");
        }
    }
}
ACompilation error due to covariance with IEnumerable
B1 2 3 4
C1 2 3
DRuntime exception due to invalid cast
Attempts:
2 left
💡 Hint
Remember that IEnumerable<out T> supports covariance and LINQ works on IEnumerable.

Practice

(1/5)
1.

What does the out keyword do when used in a generic interface in C#?

easy
A. It makes the generic type parameter covariant, allowing assignment of derived types to base types.
B. It makes the generic type parameter contravariant, allowing assignment of base types to derived types.
C. It restricts the generic type parameter to value types only.
D. It allows the generic type parameter to be used as an input parameter only.

Solution

  1. Step 1: Understand covariance in C# generics

    Covariance allows a more derived type to be assigned to a less derived type safely, typically for output positions.
  2. Step 2: Role of out keyword

    The out keyword marks a generic type parameter as covariant, enabling this safe assignment.
  3. Final Answer:

    It makes the generic type parameter covariant, allowing assignment of derived types to base types. -> Option A
  4. Quick Check:

    Covariance = out keyword [OK]
Hint: Remember: out means output, so covariance applies [OK]
Common Mistakes:
  • Confusing covariance with contravariance
  • Thinking out restricts to value types
  • Assuming out allows input parameters
2.

Which of the following is the correct syntax to declare a covariant generic interface named IReadOnlyList with type parameter T?

?
easy
A. interface IReadOnlyList { T GetItem(int index); }
B. interface IReadOnlyList { void Add(T item); }
C. interface IReadOnlyList<T> { void Add(T item); }
D. interface IReadOnlyList { T GetItem(int index); }

Solution

  1. Step 1: Identify covariance syntax

    Covariance uses the out keyword before the generic type parameter in the interface declaration.
  2. Step 2: Check method signatures

    Covariant type parameters can only be used in output positions (like return types), so T GetItem(int index) is valid, but void Add(T item) is not.
  3. Final Answer:

    interface IReadOnlyList<out T> { T GetItem(int index); } -> Option D
  4. Quick Check:

    Covariant interface = out T with output methods [OK]
Hint: Covariant types use out and only return T, no input params [OK]
Common Mistakes:
  • Using in instead of out for covariance
  • Including input parameters of type T in covariant interfaces
  • Omitting the out keyword
3.

Consider the following code snippet:

interface IProducer { T Produce(); }
class Animal { }
class Dog : Animal { }

IProducer<Dog> dogProducer = new DogProducer();
IProducer<Animal> animalProducer = dogProducer;
Animal animal = animalProducer.Produce();

What is the output or result of this code?

medium
A. Compilation error due to invalid assignment from IProducer<Dog> to IProducer<Animal>.
B. The code compiles and runs, returning an Animal object from Produce().
C. Runtime error because of invalid cast between Dog and Animal.
D. The Produce() method returns null.

Solution

  1. Step 1: Understand covariance with out

    The interface IProducer<out T> is covariant, so IProducer<Dog> can be assigned to IProducer<Animal>.
  2. Step 2: Analyze the code behavior

    The assignment is valid and Produce() returns a Dog instance, which is safely assigned to an Animal variable.
  3. Final Answer:

    The code compiles and runs, returning an Animal object from Produce(). -> Option B
  4. Quick Check:

    Covariance allows assignment and safe return [OK]
Hint: Covariant interfaces allow assignment from derived to base types [OK]
Common Mistakes:
  • Expecting compilation error on assignment
  • Confusing covariance with contravariance
  • Thinking runtime cast error will occur
4.

Given the interface declaration interface IConsumer { void Consume(T item); }, what is the problem with this code?

medium
A. The interface should use in instead of out for input parameters.
B. No problem; the code compiles and works fine.
C. Compilation error because out cannot be used with input parameters like T item.
D. Runtime error due to invalid variance usage.

Solution

  1. Step 1: Understand variance rules for out

    The out keyword marks a type parameter as covariant, which means it can only be used in output positions (return types), not input parameters.
  2. Step 2: Analyze the interface method

    The method void Consume(T item) uses T as an input parameter, which is not allowed for covariant type parameters.
  3. Final Answer:

    Compilation error because out cannot be used with input parameters like T item. -> Option C
  4. Quick Check:

    out forbids input parameters [OK]
Hint: Covariant out types cannot appear as method inputs [OK]
Common Mistakes:
  • Using out with input parameters
  • Confusing out with in keyword
  • Ignoring compiler errors on variance misuse
5.

You have the following interfaces and classes:

interface ISource { T Get(); }
interface ITarget { void Set(T item); }
class Fruit { }
class Apple : Fruit { }

ISource<Apple> appleSource = new AppleSource();
ITarget<Fruit> fruitTarget = new FruitTarget();

Which of the following assignments is valid and why?

hard
A. Assigning ISource<Apple> to ISource<Fruit> is valid due to covariance.
B. Assigning ITarget<Fruit> to ITarget<Apple> is valid due to covariance.
C. Assigning ISource<Fruit> to ISource<Apple> is valid due to contravariance.
D. Assigning ITarget<Apple> to ITarget<Fruit> is valid due to contravariance.

Solution

  1. Step 1: Recall variance keywords

    ISource<out T> is covariant, allowing assignment from ISource<Derived> to ISource<Base>. ITarget<in T> is contravariant, allowing assignment from ITarget<Base> to ITarget<Derived>.
  2. Step 2: Analyze each assignment

    Assigning ISource<Fruit> to ISource<Apple> is valid due to contravariance. reverses covariance (base to derived invalid). Assigning ITarget<Fruit> to ITarget<Apple> is valid due to covariance.: valid contravariant assignment but wrong reason (not covariance). Assigning ISource<Apple> to ISource<Fruit> is valid due to covariance.: valid covariant (derived Apple to base Fruit). Assigning ITarget<Apple> to ITarget<Fruit> is valid due to contravariance. reverses contravariance (derived to base invalid).
  3. Final Answer:

    Assigning ISource<Apple> to ISource<Fruit> is valid due to covariance. -> Option A
  4. Quick Check:

    Covariance allows derived to base assignment [OK]
Hint: Covariant = out = derived to base; Contravariant = in = base to derived [OK]
Common Mistakes:
  • Mixing covariance and contravariance directions
  • Assuming contravariance applies to output interfaces
  • Confusing type parameter usage in assignments
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard