# C# Generic

## Introduction

Hello all, today I back with another [C#](https://www.lncodes.com/series/csharp) topic, and today I will share what i learned about C# Generic. I hope with this article you will know more about C# Generic and use it on your project.

## What It Is?

Introduced in C# 2.0, generic provide a placeholder mechanism for defining types in classes, interfaces, or methods that can be replaced with specific types as needed, such as `int`, `float`, or `string`. These placeholders, known as type parameters, allow the same code to work with different data types while maintaining type safety.

## Why Implement It?

There are several pros and cons to consider before implement a generic in our project. Here are some of them:

### Pros

* Enhance code reusability.
    
* Reducing runtime errors related to type mismatches.
    
* Reduce the need to boxing and unboxing by enabling operations on value types directly.
    

### Cons

* Could potentially increase code size.
    
* It may be challenging for new programmers to understand.
    
* Could potentially impact performance because the Just-In-Time (JIT) compiler generates specific code for each generic type.
    

## How It Works?

To understand how generic work in the system, let's implement it first. To implement a generic, all you need to do is add `<T>` after the method or class name, as shown in the code below:

```csharp
namespace Lncodes.Example.Generic;

public sealed class QuizController<TQuestion, TCorrectAnswer>
{
    private readonly TQuestion _question;
    private readonly TCorrectAnswer _correctAnswer;

    public QuizController(TQuestion question, TCorrectAnswer correctAnswer) =>
       (_question, _correctAnswer) = (question, correctAnswer);
}
```

In the code above, I created a generic `QuizController` class with generic variables named `_question` and `_correctAnswer`. By using generic, I can customize the `_question` and `_correctAnswer` variable types as needed. After implementing generic, here's what happens in the system:

1. When a generic type is defined using a specific reference type, the compiler sets up the generic class with a flexible type parameter. For example, if a `QuizController<T>` class is defined with the `int` type, the compiler prepares the class for this specific type in Microsoft Intermediate Language (MSIL).
    
2. When a specific generic class is prepared and the program is running, the Just-In-Time (JIT) compiler generates a specialized version of the generic type. For example, if `QuizController<T>` is instantiated with the `int` type, the JIT compiler creates a `QuizController<int>` class at runtime.
    
3. When a generic type is initialized with previously used type parameters, the system reuses the specialized version of the generic type that was already created by the JIT compiler. This reuse reduces the amount of generated code by minimizing the number of specialized classes created by the JIT compiler.
    
4. When assigning a type to a generic, the system by default allows any type to be assigned. However, adding a constraint limits which types can be used. To add a constraint, use the `where` keyword after the class name. For example, in `QuizController where TAnswer : List`, the `TAnswer` type must be a `List` or any class that inherits from `List`.
    

## Console Application

In my console application, I use generic for my `QuizController` class, allowing me to customize the types of question, answer, and choices based on my needs.

Below is a list of the classes I used to create this console application, along with a brief explanation of each class:

| Class | Description |
| --- | --- |
| QuizController | This class is used to manage quiz-related operations such as adding and deleting items. |
| Program | This class is used to display the quiz operation on the console. |

%[https://youtu.be/FDb6rEfDuRU] 

In the video above, the console application demonstrates three quiz variations, each using different data types for the answers and choices. All of these variations are managed by a single generic class called `QuizController`.

By using generic, handling different data types within a single class is greatly simplified. Instead of creating multiple versions of a class to accommodate different data types, a single generic class can be used to handle any type. This flexibility ensures that the code remains cleaner, more consistent, and easier to maintain over time, while also reducing the complexity of managing similar classes.

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">The source code for this console application can be viewed and downloaded at&nbsp;<a target="_blank" rel="noopener nofollow" class="text-editor-link" href="https://github.com/lncodes/csharp-generic" style="pointer-events: none">Project Repository – Github.</a></div>
</div>

## Additional Information

I have discovered some additional information about C# Generic. If you have any additional information about C# Generic that you'd like to share, please feel free to leave a comment.

### Naming Guidelines

When implementing generics, following specific naming guidelines can help ensure code readability and consistency. Here are some naming conventions recommended by Microsoft:

* Do use a 'T' prefix with descriptive names for generic type parameters, e.g. `QuizController<TQuestion>`.
    
* Consider using the single character 'T' for generic type parameters when there is only one type parameter, e.g. `QuizController<T>`.
    
* Consider using names that indicate the constraints of generic type parameters when the generic has constraints, e.g. `QuizController<TChoicesCollection> where TChoicesCollection : ICollection`.
    

### Further Discoveries

Here are some further discoveries I have gathered from various sources that may provide a deeper understanding of C# Generic:

* Use generic instead of `object` or `dynamic` types whenever possible. `Object` requires boxing and unboxing processes, and `dynamic` requires runtime type resolution processes, both of which can lead to performance issues. Generic avoid these issues by removing the need for boxing, unboxing, and runtime type resolution, leading to better performance.
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">ℹ</div>
    <div data-node-type="callout-text">Boxing is the process of converting a value type, such as <code>int</code>, <code>float</code>, or <code>char</code>, into an <code>object</code> type. Unboxing is the process of converting an <code>object</code> type into a value type.</div>
    </div>
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">ℹ</div>
    <div data-node-type="callout-text">Runtime type resolution is the process of checking the actual type of a variable, determining its specific type at runtime, and performing operations based on this type to ensure type safety.</div>
    </div>
    
* A generic method can be called without explicitly specifying the type parameter. For example, a generic method `CheckAnswer<int>(int answer)` can be invoked using `CheckAnswer(1)` instead of `CheckAnswer<int>(1)`. The compiler automatically infers the type parameter based on the provided argument.
    
* A reflection can be used to get information about generic type at the runtime.
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">💡</div>
    <div data-node-type="callout-text">To learn more about C# Reflection, check out my post at <a target="_blank" rel="noopener" class="text-editor-link" href="https://lncodes.com/csharp-reflection" style="pointer-events: none">C# Reflection - Last Night Codes</a>.</div>
    </div>
    

## Reference

1. [C# Generic – Microsoft](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/)
    
2. [C# Generic Constraints – Microsoft](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters)
    
3. [C# Generic Naming Guidelines - Microsoft](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-generic-type-parameters)
    
4. [Pros And Cons U](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names#naming-conventions)[sing C# Generic – Microsoft](https://docs.microsoft.com/en-us/dotnet/standard/generics/)
