> ## 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 Method

A generic method in C# is a method declared with one or more type parameters, allowing the method's signature and implementation to operate on unspecified data types while enforcing strict compile-time type safety. By deferring the specification of the data type until the method is invoked, generic methods eliminate the performance overhead of boxing/unboxing operations and the runtime risks of downcasting associated with `System.Object`.

## Syntax and Anatomy

A generic method is defined by appending a type parameter list, enclosed in angle brackets (`< >`), immediately after the method name and before the method parameter list.

```csharp theme={"dark"}
public class ExampleClass
{
    public void MethodName<T1, T2>(T1 parameter1, T2 parameter2)
    {
        // Method implementation
    }
}
```

* **Type Parameter (`T1`, `T2`)**: The placeholder for the type that will be provided by the caller. By convention, single type parameters are named `T`, while multiple parameters use descriptive names prefixed with 'T' (e.g., `TKey`, `TValue`).
* **Type Argument**: The actual, concrete data type (e.g., `int`, `string`, `Customer`) supplied when the method is invoked.

## Invocation and Type Inference

When invoking a generic method, you can explicitly provide the type arguments. However, the C# compiler features a robust type inference engine that can automatically deduce the type arguments based on the types of the arguments passed into the method parameters.

```csharp theme={"dark"}
using System;

public class GenericDemo
{
    public void DisplayType<T>(T value) 
    {
        Console.WriteLine(typeof(T).Name);
    }

    public void Execute()
    {
        // Explicit invocation
        DisplayType<int>(42);

        // Implicit invocation via type inference
        DisplayType(42); 
    }
}
```

*Note: Type inference relies strictly on method arguments. The compiler cannot infer type parameters based solely on the method's return type or local variable assignments.*

## Generic Type Constraints

Without constraints, an unconstrained type parameter `T` can resolve to either a reference type or a value type. Consequently, the compiler only allows you to access members defined on `System.Object`. To access specific members or enforce type rules, you apply constraints using the `where` contextual keyword. Constraints restrict the kinds of types that can be substituted for a type parameter.

```csharp theme={"dark"}
using System;

public class Factory
{
    public T CreateAndFormat<T>(T input) where T : class, IFormattable, new()
    {
        T instance = new T();
        // Implementation
        return instance;
    }
}
```

Common constraints include:

* `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 (contains no reference types at any level of nesting).

## Overload Resolution

Generic methods participate in method overloading. You can overload methods based on the number of type parameters, as well as the standard method parameter signatures.

```csharp theme={"dark"}
public class Processor
{
    public void Process(int value) { }           // Non-generic
    public void Process<T>(T value) { }          // Generic with one type parameter
    public void Process<T, U>(T value, U id) { } // Generic with two type parameters
}
```

During compilation, if a caller invokes `Process(42)`, the compiler's overload resolution rules will prefer the non-generic `Process(int)` over the generic `Process<T>(T)` because exact, non-generic matches are given higher precedence than generic substitutions.

## Compilation and Runtime Behavior

Unlike Java's type erasure, C# implements reified generics. The type parameters are preserved in the compiled Intermediate Language (IL) and resolved by the Just-In-Time (JIT) compiler at runtime.

* **For Reference Types**: The JIT compiler generates a single native code implementation that is shared across all reference type arguments (e.g., `string`, `object`, custom classes), because all object references are the same size in memory.
* **For Value Types**: The JIT compiler generates a distinct, specialized native code implementation for each unique value type argument (e.g., `int`, `double`, custom structs) to accommodate their differing memory footprints and alignment requirements.

<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>
