2012-09-20 36 views
10

Tôi không hiểu các khai báo lớp sau:Mục đích của việc đặt tên lớp giữa các ký hiệu "Ít hơn" và "Lớn hơn" trong C# là gì?

public abstract class Class1 <TDomainServiceContract, TDomainService> 
{ 
    ... 
} 

Tôi biết những gì TDomainServiceContractTDomainService là, nhưng tại sao chúng được sử dụng giữa <> biểu tượng?

+2

Chúng là [thông số loại chung] (http://msdn.microsoft.com/en-us/library/ms172192.aspx). – verdesmarald

+1

cảm ơn, nhưng tại sao bạn yêu cầu đóng câu hỏi này, như một số người dùng khác, nói rằng đó không phải là một câu hỏi thực sự? Tôi thấy rằng trong "tin nhắn" của tôi có một dấu chấm hỏi, có thể nó không được hiển thị trong trình duyệt của bạn? Tôi cần phải hiểu cách trang web này hoạt động ... –

Trả lời

26

Các tham số giữa các thông số <> là các thông số loại chung. Generics, ở mức độ rất cao, cho phép bạn thiết kế một lớp không thuyết phục về loại cụ thể của một hoặc nhiều tham số, thuộc tính hoặc phương thức của nó. Đó là một chút khó khăn để giải thích bằng lời nói, nhưng việc sử dụng phổ biến nhất của Generics là trong bộ sưu tập.

Trước khi generics, hầu hết các nhà phát triển sử dụng những thứ như ArrayList để theo dõi các bộ sưu tập của các đối tượng. Nhược điểm này là an toàn; vì bạn có thể đặt bất kỳ object nào trong một ArrayList, điều đó có nghĩa là bạn phải đưa đối tượng của mình trở lại loại mong đợi (tạo mã ít sạch hơn) và bạn không có gì ngăn bạn thêm một thứ gì đó mà không phải là loại đối tượng đó (tức là tôi có thể có một ArrayList mà tôi có thể mong đợi chỉ chứa string đối tượng, nhưng tôi có thể - vô tình - đặt trong một số int hoặc DbConnection, v.v.) và bạn sẽ không bao giờ tìm hiểu cho đến khi chạy khi truyền thất bại.

ArrayList myStrings = new ArrayList(); 

myStrings.Add("foo"); 
myStrings.Add("bar"); 
myStrings.Add(1); // uh-oh, this isn't going to turn out well... 

string string1 = (string)myStrings[0]; 
string string2 = (string)myStrings[1]; 
string string3 = (string)myStrings[2]; // this will compile fine but fail at 
             // runtime since myStrings[2] is an int, 
             // not a string 

Sau khi Generics được giới thiệu, chúng tôi có lớp List<T>. Đây là một lớp duy nhất có một đối số kiểu chung duy nhất - cụ thể là, loại đối tượng mà bạn đang mong đợi danh sách chứa.Theo cách đó, tôi có thể có một số List<string> hoặc List<int> sẽ a) không yêu cầu truyền, vì các chỉ mục trả về stringint tương ứng và b) an toàn vào thời gian biên dịch, vì tôi biết rằng không có gì khác ngoài string hoặc int (một lần nữa, tương ứng) có thể được đưa vào các danh sách đó.

List<string> myStrings = new List<string>(); 

myStrings.Add("foo"); 
myStrings.Add("bar"); 
myStrings.Add(1); // this will not compile, as an int is not a string 

Mấu chốt của Generics là để nói rằng bạn không quan tâm đến những gì các loại thực tế là của đối tượng mà bạn đang làm việc với, nhưng người tiêu dùng của sức lớp học của bạn. Nói cách khác, cơ chế về cách danh sách có thể lưu trữ một số string, một số int, một số DbConnection, v.v ..., nhưng generics làm cho nó để thông tin kiểu này đến từ người tiêu dùng lớp học của bạn không bị mất trong trừu tượng của bạn.

+2

+1 Tôi mới bắt đầu học C# và đây chính xác là những gì tôi cần. Chúc mừng! – AlienWebguy

1

Điều này cho thấy rằng khi sử dụng lớp, bạn có thể cung cấp bất kỳ loại nào cho số TDomainServiceContract triển khai DomainContext. Vì vậy, chúng ta hãy giả định một lớp học như thế này:

public class MyDomainContext : DomainContext 
{ 
    ... 
} 

tôi có thể sử dụng lớp đó khi tạo mới Class1 như thế này:

var o = new Class1<MyDomainContext, MyDomainService>(); 

bởi vì nó thực hiện DomainContext. Điều tương tự cũng xảy ra với số TDomainService.

1

Một cách khác để xem xét nó là một ví dụ đơn giản hơn. Ví dụ:

List<String> myStrings = new List<String>(); 
myStrings.Add("One"); 
//Etc. 

Trong ví dụ này, bạn chỉ cần xác định loại dữ liệu bạn sẽ sử dụng với lớp. Tình huống tương tự trong ví dụ của bạn.

Các vấn đề liên quan