Generic ràng buộc
C#
public class Repository<T> where T : class, new()
{
public T CreateInstance()
{
return new T();
}
}
public class RefTypeCustom
{
//public RefTypeCustom(int a) // Constructor không được có tham số
//{
//}
public RefTypeCustom()
{
}
}
public class Program
{
public static void Main(string[] args)
{
// var test1 = new Repository<int>(); // Lỗi không phải kiểu reference
var test3 = new Repository<RefTypeCustom>();
}
}
where T : class -> Kiểu phải là tham chiếu
where T : new() -> Constructor không được có tham số
Generic Interfaces
Cùng xem ví dụ:
Chúng ta có thể tạo một Interface có generic , khi lớp CustomerRepository kế thừa interface sẽ thực thi các phương thức trong interface tương ứng
C#
namespace GenericInCs
{
public interface IRepository<T>
{
void Add(T item);
T GetById(int id);
}
public class CustomerRepository : IRepository<Customer>
{
void IRepository<Customer>.Add(Customer item)
{
/* Implementation */
}
Customer IRepository<Customer>.GetById(int id)
{
/* Implementation */
return new Customer();
}
}
public class Customer
{
}
public class Program
{
public static void Main(string[] args)
{
}
}
}
Generic Methods
Có thể tạo ra một phương thức Generic độc lập với lớp chứa nó
C#
public class FindMaxClass<K>
{
public T FindMax<T>(T x, T y) where T : IComparable<T>
{
return x.CompareTo(y) > 0 ? x : y;
}
}
Generic Delegates
Delegates cũng có thể tạo generic
C#
public class Demo
{
public T Square<T>(T x) where T : struct
{
dynamic d = x;
return (T)(d * d);
}
}
Generic Type Parameters trong Inheritance
Trong kế thừa nó cho phép base class mở rộng bởi derived class
C#
namespace GenericInCs
{
public class BaseRepository<T>
{
public virtual void Save(T entity) { /* Save entity */ }
}
public class CustomerRepository : BaseRepository<Customer>
{
public override void Save(Customer entity) { /* Specific save logic */ }
}
public class Customer
{
}
public class Program
{
public static void Main(string[] args)
{
}
}
}
Nested Generics
Bạn có thể tổ chức các generic lồng nhau
C#
public class Response<TData, TError>
{
public TData Data { get; set; }
public TError Error { get; set; }
}
public class ServiceResponse<T> : Response<T, string>
{
public bool IsSuccess { get; set; }
}
Open and Closed Types
Open: có kiểu mỗi phần tử là không nhất định, ví dụ int
Closed: có kiểu mỗi phần tử là nhất định, ví dụ có thể là int hoặc string
C#
Type closedType = typeof(List<int>); // Closed generic type
Type openType = typeof(List<>); // Open generic type
Generic Type Inference
Compiler sẽ suy luận kiểu
C#
T Add<T>(T a, T b) => (dynamic)a + (dynamic)b;
var result = Add(3, 5); // suy luận T là int