@ian.heidenreich 
В C# можно работать с генериками, используя параметризированные типы данных. Генерики позволяют создавать классы, структуры, методы и интерфейсы, которые могут работать с различными типами данных, без указания конкретного типа заранее.
Вот несколько примеров использования генериков в C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
public class MyClass { private T value; public MyClass(T value) { this.value = value; } public T GetValue() { return value; } }  | 
1 2 3 4 5 6 7 8 9 10 11 12  | 
public T FindMax(T[] array) { T max = array[0]; foreach (T item in array) { if (item > max) { max = item; } } return max; }  | 
1 2 3 4  | 
public interface IComparable { int CompareTo(T other); }  | 
1 2 3 4  | 
List numbers = new List(); numbers.Add(1); numbers.Add(2); numbers.Add(3);  | 
Генерики в C# позволяют писать более гибкий и переиспользуемый код, так как они позволяют работать с разными типами данных одновременно.
@ian.heidenreich 
Вот более подробные способы работы с генериками в C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
public class GenericList<T>
{
    private List<T> list = new List<T>();
    
    public void Add(T value)
    {
        list.Add(value);
    }
    public T Get(int index)
    {
        return list[index];
    }
}
 | 
1 2 3 4  | 
public class GenericList<T> where T : IComparable
{
    // код
}
 | 
В этом случае T должен реализовать интерфейс IComparable.
1
 | 
public delegate T AddTwoValues<T>(T value1, T value2);  | 
Такой делигат может быть использован для обобщенных методов или классов, которые принимают делегаты.
1 2 3 4 5 6  | 
public interface IRepository<T>
{
    void Add(T item);
    void Delete(T item);
    IEnumerable<T> GetAll();
}
 | 
1
 | 
Dictionary<string, int> keyValuePairs = new Dictionary<string, int>();  | 
Где string и int - обобщенные типы.
Это лишь небольшой обзор того, как можно использовать генерики в C#. Генерики широко применяются в различных сценариях программирования для создания более универсальных и гибких решений.