Đó là một phần nhỏ của cả hai. Để sử dụng một lớp chung, bạn phải cung cấp cho nó một tham số kiểu tại thời gian biên dịch, nhưng tham số kiểu có thể là một giao diện hoặc lớp cơ sở, vì vậy loại thực tế, cụ thể của các đối tượng được sử dụng trong thời gian chạy có thể khác nhau. Ví dụ, ở đây tôi có một đoạn mã với trường Stack<T>
. Tôi đã chọn sử dụng giao diện làm thông số loại. Điều này sử dụng parametric polymorphism tại thời gian biên dịch. Bạn phải chọn tham số kiểu trường _stack
của bạn sẽ sử dụng tại thời gian biên dịch:
public interface IFoo { void Foo(); }
public Stack<IFoo> _stack = new Stack<IFoo>();
Bây giờ, khi đoạn mã này thực sự là chạy, tôi có thể sử dụng bất kỳ đối tượng mà lớp thực hiện IFoo
, và quyết định rằng không có được thực hiện cho đến khi thời gian chạy:
public class Foo1 : IFoo { public void Foo() { Console.WriteLine("Foo1"); } }
public class Foo2 : IFoo { public void Foo() { Console.WriteLine("Foo2"); } }
public class Foo3 : IFoo { public void Foo() { Console.WriteLine("Foo2"); } }
_stack.Push(new Foo1());
_stack.Push(new Foo2());
_stack.Push(new Foo3());
Đây là ví dụ về subtype polymorphism, được sử dụng trong thời gian chạy.
Bạn có thể xem bài viết này: http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx – Guillaume
@Guillaume Tuyệt vời, bài viết ngắn. Tôi đang tìm kiếm thứ gì đó bằng E.L. như một tham chiếu. – FishBasketGordo