Generic

Generic — Khái niệm và cú pháp

Generic function, class, interface, method — cú pháp C# và TypeScript song song.

1. Generic function

// T là type parameter
public static T Identity<T>(T x) => x;

Identity<int>(42);          // explicit
Identity(42);               // inferred — T = int
Identity("hello");          // T = string

// Nhiều type parameter
public static (A, B) Pair<A, B>(A a, B b) => (a, b);

var p = Pair(1, "one");     // (int, string)

2. Generic class

public class Box<T> {
    public T Value { get; }
    public Box(T value) => Value = value;
    
    public Box<U> Map<U>(Func<T, U> fn) => new Box<U>(fn(Value));
}

var box = new Box<int>(42);
var stringBox = box.Map(n => n.ToString());     // Box<string>

3. Generic interface

public interface IRepository<T> where T : class {
    Task<T?> GetByIdAsync(int id);
    Task<List<T>> GetAllAsync();
    Task AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(int id);
}

public class UserRepository : IRepository<User> {
    public Task<User?> GetByIdAsync(int id) { ... }
    // ...
}

4. Generic method trong class non-generic

public class Cache {
    private readonly Dictionary<string, object> _data = new();
    
    public void Set<T>(string key, T value) => _data[key] = value!;
    
    public T? Get<T>(string key) {
        if (_data.TryGetValue(key, out var v) && v is T t) return t;
        return default;
    }
}

var c = new Cache();
c.Set("count", 42);
int n = c.Get<int>("count");      // 42

5. Default type parameter

C# không có default type parameter (như TS). Phải overload hoặc dùng helper.

// Workaround: 2 method
public class Box {
    public static Box<object> Create() => new();
    public static Box<T> Create<T>() => new();
}

6. Type inference

Cả 2 ngôn ngữ đều infer type parameter từ argument:

public static T First<T>(IEnumerable<T> items) => items.First();

First(new[] { 1, 2, 3 });       // T = int (inferred)
function first<T>(items: T[]): T { return items[0]; }
first([1, 2, 3]);               // T = number
Khi inference fail — bạn cần specify thủ công:
function create<T>(): T[] { return []; }
create();                       // T = unknown (không có gợi ý nào)
create<number>();               // ✅

7. Generic & polymorphism

Generic là dạng parametric polymorphism. Khác subtype polymorphism (kế thừa, override):

// Subtype polymorphism
Animal[] zoo = { new Dog(), new Cat() };

// Parametric polymorphism
T Identity<T>(T x) => x;
List<int> ints; List<string> strings;

Modern code thường kết hợp 2: IRepository<T> (parametric) với T : class (constraint kiểu subtype).

8. Self-referencing generic (Curiously Recurring Template Pattern)

public interface IComparable<T> {
    int CompareTo(T other);
}

public class MyNumber : IComparable<MyNumber> {
    public int Value;
    public int CompareTo(MyNumber other) => Value.CompareTo(other.Value);
}

// Builder fluent với generic self-type
public abstract class FluentBuilder<TSelf> where TSelf : FluentBuilder<TSelf> {
    public TSelf SetName(string n) {
        // ...
        return (TSelf)this;
    }
}

public class UserBuilder : FluentBuilder<UserBuilder> {
    public UserBuilder SetEmail(string e) { ... return this; }
}

new UserBuilder()
    .SetName("Alice")        // trả UserBuilder (không phải FluentBuilder!)
    .SetEmail("a@b.com");    // SetEmail vẫn gọi được

9. Generic và collection trong .NET / TS

List<int> nums = new() { 1, 2, 3 };
Dictionary<string, int> ages = new() { ["Alice"] = 25 };
HashSet<string> tags = new() { "vue", "nuxt" };
Queue<Task> jobs = new();
Stack<string> path = new();

Mọi collection chuẩn từ .NET 2.0 đều generic — tránh boxing với value type.

10. typeof parameter trong TS (đặc thù)

const colors = ["red", "green", "blue"] as const;
type Color = typeof colors[number];      // "red" | "green" | "blue"

function pick<T extends readonly unknown[]>(arr: T): T[number] {
    return arr[Math.floor(Math.random() * arr.length)];
}
const c = pick(colors);                  // "red" | "green" | "blue"

C# không có cơ chế tương đương ở compile-time (cần reflection runtime).

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.