Discover how a simple keyword can save you from tedious and error-prone type conversions!
Why Covariance with out keyword in C Sharp (C#)? - Purpose & Use Cases
Imagine you have a list of cats, but you want to use it as a list of animals without rewriting or copying the whole list.
Without covariance, you must manually convert or copy each item to the new type. This is slow, error-prone, and wastes memory.
The out keyword in C# allows safe covariance, letting you treat a collection of a more specific type as a collection of a more general type without copying.
IEnumerable<Cat> cats = new List<Cat>(); IEnumerable<Animal> animals = cats.Cast<Animal>();
IEnumerable<Cat> cats = new List<Cat>(); IEnumerable<Animal> animals = cats;
This lets you write cleaner, safer code that reuses collections without extra work or errors.
When you have a method that accepts IEnumerable<Animal>, you can pass a list of Cat directly thanks to covariance with out.
Manual type conversions are slow and risky.
out keyword enables safe covariance in interfaces.
Covariance allows flexible and reusable code with collections.
Practice
What does the out keyword do when used in a generic interface in C#?
Solution
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.Step 2: Role of
Theoutkeywordoutkeyword marks a generic type parameter as covariant, enabling this safe assignment.Final Answer:
It makes the generic type parameter covariant, allowing assignment of derived types to base types. -> Option AQuick Check:
Covariance =outkeyword [OK]
out means output, so covariance applies [OK]- Confusing covariance with contravariance
- Thinking
outrestricts to value types - Assuming
outallows input parameters
Which of the following is the correct syntax to declare a covariant generic interface named IReadOnlyList with type parameter T?
?
Solution
Step 1: Identify covariance syntax
Covariance uses theoutkeyword before the generic type parameter in the interface declaration.Step 2: Check method signatures
Covariant type parameters can only be used in output positions (like return types), soT GetItem(int index)is valid, butvoid Add(T item)is not.Final Answer:
interface IReadOnlyList<out T> { T GetItem(int index); } -> Option DQuick Check:
Covariant interface =out Twith output methods [OK]
out and only return T, no input params [OK]- Using
ininstead ofoutfor covariance - Including input parameters of type T in covariant interfaces
- Omitting the
outkeyword
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?
Solution
Step 1: Understand covariance with
The interfaceoutIProducer<out T>is covariant, soIProducer<Dog>can be assigned toIProducer<Animal>.Step 2: Analyze the code behavior
The assignment is valid andProduce()returns aDoginstance, which is safely assigned to anAnimalvariable.Final Answer:
The code compiles and runs, returning an Animal object from Produce(). -> Option BQuick Check:
Covariance allows assignment and safe return [OK]
- Expecting compilation error on assignment
- Confusing covariance with contravariance
- Thinking runtime cast error will occur
Given the interface declaration interface IConsumer { void Consume(T item); }, what is the problem with this code?
Solution
Step 1: Understand variance rules for
Theoutoutkeyword marks a type parameter as covariant, which means it can only be used in output positions (return types), not input parameters.Step 2: Analyze the interface method
The methodvoid Consume(T item)usesTas an input parameter, which is not allowed for covariant type parameters.Final Answer:
Compilation error becauseoutcannot be used with input parameters likeT item. -> Option CQuick Check:
outforbids input parameters [OK]
out types cannot appear as method inputs [OK]- Using
outwith input parameters - Confusing
outwithinkeyword - Ignoring compiler errors on variance misuse
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?
Solution
Step 1: Recall variance keywords
ISource<out T>is covariant, allowing assignment fromISource<Derived>toISource<Base>.ITarget<in T>is contravariant, allowing assignment fromITarget<Base>toITarget<Derived>.Step 2: Analyze each assignment
AssigningISource<Fruit>toISource<Apple>is valid due to contravariance. reverses covariance (base to derived invalid). AssigningITarget<Fruit>toITarget<Apple>is valid due to covariance.: valid contravariant assignment but wrong reason (not covariance). AssigningISource<Apple>toISource<Fruit>is valid due to covariance.: valid covariant (derived Apple to base Fruit). AssigningITarget<Apple>toITarget<Fruit>is valid due to contravariance. reverses contravariance (derived to base invalid).Final Answer:
Assigning ISource<Apple> to ISource<Fruit> is valid due to covariance. -> Option AQuick Check:
Covariance allows derived to base assignment [OK]
- Mixing covariance and contravariance directions
- Assuming contravariance applies to output interfaces
- Confusing type parameter usage in assignments
Ready to prove it?
Pass the test and this pattern moves unknown
