The out keyword marks a generic type parameter as covariant, allowing a method to return a more derived type than originally specified. It enables safe type substitution from a less derived type to a more derived type.
Click to reveal answer
intermediate
Why can't you use out keyword on method input parameters?
Because covariance only applies to output (return) types, using out on input parameters would break type safety. Input parameters must be contravariant (using in) or invariant.
It means IEnumerable is covariant in T. You can use IEnumerable<Base> where IEnumerable<Derived> is expected, because T is marked with out.
Click to reveal answer
intermediate
What happens if you try to use out on a generic type parameter that appears as a method input?
The compiler will give an error because covariance requires the type parameter to be used only in output positions. Using it as input breaks the covariance rule.
Click to reveal answer
beginner
How does covariance with out improve code flexibility?
It allows you to assign objects of more derived generic types to variables of less derived generic types safely, reducing the need for explicit casts and increasing code reuse.
Click to reveal answer
What does the out keyword do in a generic interface?
ADisables generic type usage
BAllows the generic type to be used only as a method input (contravariance)
CMakes the generic type invariant
DAllows the generic type to be used only as a return type (covariance)
✗ Incorrect
The out keyword marks a generic type parameter as covariant, meaning it can only be used as a return type.
Which of these is a valid use of a covariant type parameter marked with out?
AAs a method return type
BAs a method input parameter
CAs a field type for writing
DAs a method parameter passed by ref
✗ Incorrect
Covariant type parameters can only be used as return types, not as input parameters or writable fields.
Given IEnumerable<out T>, can you assign IEnumerable<string> to IEnumerable<object>?
ANo, because generics are invariant by default
BNo, because string is not object
CYes, because of covariance
DYes, but only with a cast
✗ Incorrect
Covariance allows assigning IEnumerable<string> to IEnumerable<object> safely.
What error occurs if you use out on a type parameter used as a method input?
AWarning only
BCompiler error: Invalid variance usage
CNo error, it's allowed
DRuntime exception
✗ Incorrect
The compiler enforces variance rules and will error if out is used incorrectly.
Which keyword is used for contravariance, the opposite of covariance?
Ain
Bout
Cref
Dvar
✗ Incorrect
The in keyword marks a generic type parameter as contravariant, allowing it to be used only as input.
Explain covariance in C# and how the out keyword enables it.
Think about how you can safely substitute types when returning values.
You got /4 concepts.
Describe a scenario where covariance with out is useful in a real program.
Consider collections of objects and how you might want to treat them as collections of their base type.
You got /4 concepts.
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
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 out keyword
The out keyword 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 A
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
Step 1: Identify covariance syntax
Covariance uses the out keyword 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), so T GetItem(int index) is valid, but void Add(T item) is not.
Final Answer:
interface IReadOnlyList<out T> { T GetItem(int index); } -> Option D
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
Step 1: Understand covariance with out
The interface IProducer<out T> is covariant, so IProducer<Dog> can be assigned to IProducer<Animal>.
Step 2: Analyze the code behavior
The assignment is valid and Produce() returns a Dog instance, which is safely assigned to an Animal variable.
Final Answer:
The code compiles and runs, returning an Animal object from Produce(). -> Option B
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
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.
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.
Final Answer:
Compilation error because out cannot be used with input parameters like T item. -> Option C
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
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>.
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).
Final Answer:
Assigning ISource<Apple> to ISource<Fruit> is valid due to covariance. -> Option A
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 unknownstrongwhile earning +1 Grip toward your certificate.