> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Generic Class

A generic class in C# is a blueprint that defers the specification of one or more data types until the class is instantiated by client code. By defining a class with type parameters, you create a single, strongly-typed implementation that operates uniformly across different data types without incurring the performance overhead of boxing, unboxing, or runtime type casting.

## Syntax and Structure

A generic class is declared by appending angle brackets (`<>`) containing one or more type parameters to the class name.

```csharp theme={"dark"}
public class Container<T>
{
    private T _item;

    public Container(T item)
    {
        _item = item;
    }

    public T GetItem()
    {
        return _item;
    }
}
```

## Core Terminology

* **Type Parameter:** The placeholder identifier (e.g., `T`) defined in the class declaration. It acts as a variable for a type.
* **Type Argument:** The concrete data type (e.g., `int`, `string`, `Customer`) supplied by the client code when instantiating the class (e.g., `new Container<int>(5)`).
* **Unbound Generic Type:** A generic type definition with no type arguments specified (e.g., `typeof(Container<>)`). You cannot instantiate an unbound generic type at runtime (e.g., using `Activator.CreateInstance(typeof(Container<>))`).
* **Open Constructed Type:** A generic type where at least one type argument is an unresolved type parameter (e.g., `Container<T>` used within the body of a generic class). Open constructed types cannot be instantiated. Although syntax like `new Container<T>()` is valid within generic source code, object instantiation occurs at runtime. By the time the CLR executes the instantiation, `T` has been resolved to a concrete type argument, resulting in the instantiation of a closed constructed type.
* **Closed Constructed Type:** A generic type where all type parameters have been replaced by concrete type arguments (e.g., `typeof(Container<int>)`).

## Multiple Type Parameters

Generic classes can declare multiple type parameters, separated by commas. Standard naming conventions dictate prefixing type parameters with `T` followed by a descriptive name.

```csharp theme={"dark"}
public class KeyValuePair<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}
```

## Type Constraints

By default, an unconstrained type parameter is an unknown, strongly-typed placeholder that merely allows access to the members defined in `System.Object`. To safely invoke specific methods or enforce structural requirements on the type argument, you apply constraints using the `where` contextual keyword.

```csharp theme={"dark"}
public class DataProcessor<T> where T : class, IDisposable, new()
{
    public void Process()
    {
        // 'new()' constraint allows instantiation
        T instance = new T(); 
        
        // 'IDisposable' constraint allows calling Dispose()
        instance.Dispose();   
    }
}
```

**Common Constraints:**

* `where T : struct`: Must be a non-nullable value type.
* `where T : class`: Must be a reference type.
* `where T : notnull`: Must be a non-nullable type (value or reference).
* `where T : new()`: Must have a public parameterless constructor.
* `where T : <BaseClass>`: Must be or derive from the specified base class.
* `where T : <Interface>`: Must implement the specified interface.
* `where T : unmanaged`: Must be an unmanaged type (no reference type fields).

## Static Members in Generic Classes

Static fields and properties in a generic class are not shared globally across all instances of the generic definition. Instead, they are shared only among instances of the same **closed constructed type**.

```csharp theme={"dark"}
public class StateTracker<T>
{
    public static int InstanceCount;

    public StateTracker()
    {
        InstanceCount++;
    }
}

// Usage mechanics:
new StateTracker<int>();
new StateTracker<int>();
new StateTracker<string>();

// StateTracker<int>.InstanceCount == 2
// StateTracker<string>.InstanceCount == 1
```

The CLR generates distinct memory layouts and static fields for `StateTracker<int>` and `StateTracker<string>`.

## Inheritance Mechanics

Generic classes can participate in inheritance hierarchies. A class can inherit from a closed constructed type or propagate its own type parameters to an open constructed base class.

```csharp theme={"dark"}
public class BaseNode<T> { }

// 1. Inheriting and closing the generic type
public class IntNode : BaseNode<int> { }

// 2. Inheriting and propagating the type parameter
public class GenericNode<T> : BaseNode<T> { }

// 3. Adding new type parameters while propagating
public class ComplexNode<T, U> : BaseNode<T> { }
```

When inheriting from a generic base class, any constraints applied to the base class's type parameters must be duplicated or satisfied by the derived class's type parameters.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
