---
title: "What is covariance and contravariance?"  
description: "What is covariance and contravariance?"  
author: "Anubhav Sharma"  
published: 2025-06-19  
updated: 2025-07-24  
canonical: https://www.mindstick.com/forum/161737/what-is-covariance-and-contravariance  
category: "c#"  
tags: ["c#"]  
reading_time: 2 minutes  

---

# What is covariance and contravariance?

What is [covariance and contravariance](https://www.mindstick.com/interview/34247/explain-the-difference-between-covariance-and-contravariance), [explain](https://www.mindstick.com/forum/157854/what-is-system-debugging-explain-some-system-debugging-tools-used-in-modern-computer-systems) with example?

## Replies

### Reply by Ravi Vishwakarma

Covariance and contravariance are concepts in C# that deal with **type compatibility** in **generic interfaces, delegates, and method parameters/returns**, especially when dealing with **inheritance hierarchies**.

They allow **flexibility in assigning** types that are **related by inheritance** — while maintaining type safety.

## Covariance (Output flexibility — `out`)

- **Allows a more derived type to be used** than originally specified.
- Applies to **return types** (output).
- Declared using the `out` keyword (for **generic type parameters**).
- Common in **interfaces** like `IEnumerable<out T>` or **delegates**.

### Example:

```cs
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings; // ✅ Covariant: string → object
```

```cs
public interface ICovariant<out T>
{
    T GetItem(); // Output only
}
```

## Contravariance (Input flexibility — `in`)

- **Allows a more generic (base) type to be used** than originally specified.
- Applies to **method parameters** (input).
- Declared using the `in` keyword (for **generic type parameters**).
- Common in **delegates** like `Action<in T>` or interfaces like `IComparer<in T>`.

### Example:

```cs
Action<object> actObj = o => Console.WriteLine(o);
Action<string> actStr = actObj; // ✅ Contravariant: object ← string
```

```cs
public interface IContravariant<in T>
{
    void SetItem(T item); // Input only
}
```

## Summary Table

| Concept | Keyword | Direction | Applies To | Example |
| --- | --- | --- | --- | --- |
| Covariance | `out` | Output | Return types | `IEnumerable<out T>` |
| Contravariance | `in` | Input | Parameters | `Action<in T>` |

## Real-World Use Case

### Covariance

You can assign `IEnumerable<string>` to `IEnumerable<object>` because strings are objects:

```cs
IEnumerable<string> names = new List<string>();
IEnumerable<object> objs = names; // ✅
```

### Contravariance

A method that accepts `object` can be used where a method accepting `string` is expected:

```cs
Action<object> log = x => Console.WriteLine(x);
Action<string> logStr = log; // ✅
```

## When to Use

- Use **covariance** when your generic type is **used only for return values**.
- Use **contravariance** when your generic type is **used only for method parameters**.


---

Original Source: https://www.mindstick.com/forum/161737/what-is-covariance-and-contravariance

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
