2010-08-31 31 views
24

Tôi đã xem xét một số mã mẫu sử dụng C# generics. Tại sao và khi nào tôi nên sử dụng chúng?Hiểu về C# generics tốt hơn nhiều

Tất cả các ví dụ đều phức tạp. Tôi cần một ví dụ đơn giản, rõ ràng giúp tôi bắt đầu với các C# Generics.

+8

Xem [câu hỏi này] (http://stackoverflow.com/questions/77632/what-is-cool-about -generics-why-use-them). –

+0

Xem: http://www.csharp-station.com/Tutorials/Lesson20.aspx – kenorb

Trả lời

50

Một ví dụ rất đơn giản là lớp chung List<T>. Nó có thể chứa một số đối tượng thuộc bất kỳ loại nào. Ví dụ, bạn có thể khai báo một danh sách các chuỗi (new List<string>()) hoặc một danh sách các động vật (new List<Animal>()), bởi vì nó là chung chung.

Nếu bạn không thể sử dụng Generics thì sao? Bạn có thể sử dụng lớp ArrayList, nhưng nhược điểm là nó chứa loại là object. Vì vậy, khi bạn lặp lại trong danh sách, bạn phải truyền mọi mục theo đúng loại (hoặc string hoặc Animal) là mã nhiều hơn và có hình phạt về hiệu suất. Ngoài ra, vì ArrayList chứa các đối tượng nên nó không an toàn. Bạn vẫn có thể thêm một Animal một ArrayList của chuỗi:

ArrayList arrayList = new ArrayList(); 
arrayList.Add(new Animal()); 
arrayList.Add(""); 

Vì vậy, khi lặp lại một ArrayList bạn phải kiểm tra các loại để đảm bảo các trường hợp là của một loại hình cụ thể, mà kết quả trong mã nghèo:

foreach (object o in arrayList) 
{ 
    if(o is Animal) 
    ((Animal)o).Speak(); 
} 

với generic List<string>, điều này chỉ đơn giản là không thể:

List<string> stringList = new List<String>(); 
stringList.Add("Hello"); 
stringList.Add("Second String"); 
stringList.Add(new Animal()); // error! Animal cannot be cast to a string 
+3

Câu trả lời hay. Dễ dàng để làm theo. – RKh

+0

+1 để có thể đưa ra một ví dụ đẹp, rõ ràng và không phức tạp. Làm tốt. – Subby

+0

bây giờ đó là những gì chúng tôi gọi là một lời giải thích cơ bản, với các ví dụ tuyệt vời, có đoạn mã thời gian thực. Tuyệt quá. +1 – Kings

0

Tóm lại, Generics cho phép bạn viết các lớp học tha t làm việc với các đối tượng thuộc bất kỳ loại nào, nhưng không phải truyền dữ liệu đến Object. Có lợi ích hiệu suất cho việc này, nhưng nó cũng làm cho mã của bạn dễ đọc hơn, dễ bảo trì hơn và ít bị lỗi hơn.

Bạn nên luôn luôn sử dụng Generics như trái ngược với các lớp phong cách .NET 1.1 khi có thể.

5

Để tóm tắt câu trả lời khác với một số nhấn mạnh:

1) Generics cho phép bạn viết mã 'chung' (ví dụ, nó sẽ làm việc cho nhiều loại). Nếu bạn có hành vi 'chung' mà bạn muốn viết, bạn cần phải xử lý các loại dữ liệu khác nhau, bạn chỉ cần viết mã đó một lần. Các ví dụ về Danh sách là một ví dụ tuyệt vời, bạn có thể cần danh sách có lẽ khách hàng, sản phẩm, đơn đặt hàng, nhà cung cấp ... tất cả bằng cách sử dụng cùng một mã khởi tạo cho mỗi loại

// snippet 
List<Customer> customers = new List<Customer>(); 
Customer thisCustomer = new Customer(); 
customers.Add(thisCustomer); 

List<Order> orders = new List<Order>(); 
Order thatOrder = new Order(); 
orders.Add(thatOrder); 

// etc. 

2) ngạc nhiên, generics vẫn cho phép loại an toàn ! Vì vậy, nếu bạn cố gắng này, bạn sẽ nhận được một cách đúng đắn lỗi:

// continued for snippet above 
Order anotherOrder = new Order(); 
customers.Add(anotherOrder); // FAIL! 

Và bạn sẽ muốn điều đó là một lỗi, vì vậy mà sau này trên mã xử lý khách hàng của bạn không nhất thiết phải xử lý một trật tự giả mạo hiển thị trong danh sách khách hàng.

+0

Tôi ước gì tôi đã nói những gì Unmesh nói: "Trùng lặp là gốc rễ của mọi điều ác". – Jay

3

Sao chép là gốc của tất cả các điều ác. Một trường hợp trùng lặp mã xảy ra khi bạn phải thực hiện thao tác tương tự trên các loại dữ liệu khác nhau. Generics cho phép bạn tránh nó bằng cách cho phép bạn mã hóa xung quanh một loại 'chung' và sau đó thay thế nó bằng các loại cụ thể.

Giải pháp khác cho vấn đề này là sử dụng các biến kiểu 'System.Object' cho bất kỳ loại đối tượng nào có thể được gán. Phương pháp này liên quan đến hoạt động boxing và unboxing giữa giá trị và các loại tham chiếu có hiệu suất đạt được.Ngoài ra, việc nhập khuôn sẽ giữ cho mã không bị xóa.

Generics được hỗ trợ trong MSIL và CLR mà làm cho nó hoạt động thực sự tốt.

Bạn nên đọc những bài viết về Generics -

http://msdn.microsoft.com/en-us/library/512aeb7t(VS.80).aspx

http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx#csharp_generics_topic1

+2

Có rất nhiều nguồn gốc của tất cả các điều ác, như tối ưu hóa sớm và thậm chí là sự khái quát hóa sớm;) –