2012-03-25 31 views
43

Tôi mới đến C# và trực tiếp lặn vào sửa đổi một số mã cho một dự án tôi nhận được. Tuy nhiên, tôi cứ nhìn thấy mã như thế này:Những gì hiện <T> biểu thị trong C#

class SampleCollection<T> 

và tôi không thể làm cho tinh thần của những gì

<T> 

phương tiện hay những gì nó được gọi.

Nếu có ai quan tâm để giúp tôi chỉ đặt tên cho khái niệm này được gọi là gì, tôi có thể tìm kiếm nó trực tuyến. Tuy nhiên, tôi không biết gì về bây giờ.

+0

Ngắt của http://stackoverflow.com/questions/361336/what-are-generic-collections-in-c#361365 và http://stackoverflow.com/questions/400314/what-does-t-mean -in-c. – Abel

+0

Sao chép nhiều người khác, nhưng cũng không có chủ đề như những người khác vì nó yêu cầu [tài liệu] (http://msdn.microsoft.com/en-us/library/512aeb7t.aspx) hoặc hướng dẫn. –

Trả lời

71

Đây là Generic Type Parameter.

Thông số kiểu chung cho phép bạn chỉ định một kiểu T tùy ý cho một phương thức tại thời gian biên dịch, mà không chỉ định một loại cụ thể trong khai báo phương thức hoặc lớp.

Ví dụ:

public T[] Reverse<T>(T[] array) 
{ 
    var result = new T[array.Length]; 
    int j=0; 
    for(int i=array.Length; i>= 0; i--) 
    { 
     result[j] = array[i]; 
     j++; 
    } 
    return result; 
} 

đảo ngược các yếu tố trong một mảng. Điểm mấu chốt ở đây là các phần tử mảng có thể thuộc bất kỳ kiểu nào và hàm sẽ vẫn hoạt động. Bạn chỉ định loại trong cuộc gọi phương thức; loại an toàn vẫn được đảm bảo.

Vì vậy, để đảo ngược một mảng của chuỗi:

string[] array = new string[] { "1", "2", "3", "4", "5" }; 
var result = reverse(array); 

Sẽ tạo ra một mảng chuỗi trong result của { "5", "4", "3", "2", "1" }

này có tác dụng tương tự như khi bạn được gọi là bình thường (không phải chung chung) phương pháp giống như sau:

public string[] Reverse(string[] array) 
{ 
    var result = new string[array.Length]; 
    int j=0; 
    for(int i=array.Length; i >= 0; i--) 
    { 
     result[j] = array[i]; 
     j++; 
    } 
    return result; 
} 

Trình biên dịch thấy rằng array chứa chuỗi, vì vậy nó trả về một mảng ngs. Loại string được thay thế cho thông số loại T.


Thông số loại chung cũng có thể được sử dụng để tạo các lớp chung. Trong ví dụ bạn đã cho một số SampleCollection<T>, T là trình giữ chỗ cho loại tùy ý; nó có nghĩa là SampleCollection có thể đại diện cho một bộ sưu tập các đối tượng, loại mà bạn chỉ định khi bạn tạo bộ sưu tập.

Vì vậy:

var collection = new SampleCollection<string>(); 

tạo ra một bộ sưu tập có thể chứa chuỗi. Phương thức Reverse được minh họa ở trên, ở dạng hơi khác, có thể được sử dụng để đảo ngược thành viên của bộ sưu tập.

+0

theo cách nào có thể xác định một tham số kiểu chung T trong thời gian chạy? –

+0

@mikez: http://stackoverflow.com/questions/513952/c-sharp-specifying-generic-collection-type-param-at-runtime –

+2

Có, mặc dù bạn có thể khởi tạo các lớp chung với tham số kiểu tại thời gian chạy bằng cách sử dụng sự phản chiếu , nó là khó hiểu khi nói rằng bạn sử dụng generics để xác định một loại tại thời gian chạy, nơi bạn sử dụng bình thường chỉ định một lúc biên dịch thời gian. – SoftMemes

6

Tính năng này được gọi là generics. http://msdn.microsoft.com/en-us/library/512aeb7t(v=vs.100).aspx

Ví dụ về việc này là tạo một tập hợp các mục thuộc một loại cụ thể.

class MyArray<T> 
{ 
    T[] array = new T[10]; 

    public T GetItem(int index) 
    { 
     return array[index]; 
    } 
} 

Trong code của bạn, sau đó bạn có thể làm một cái gì đó như thế này:

MyArray<int> = new MyArray<int>(); 

Trong trường hợp này, T[] array sẽ làm việc như int[] array, và public T GetItem sẽ làm việc như public int GetItem.

11

Đây là thông số loại chung, see Generics documentation.

T không phải là từ khóa dành riêng. T, hoặc bất kỳ tên cụ thể nào, có nghĩa là thông số loại. Kiểm tra các phương pháp sau đây (giống như một ví dụ đơn giản).

T GetDefault<T>() 
{ 
    return default(T); 
} 

Lưu ý rằng kiểu trả về là T. Với phương pháp này bạn có thể nhận giá trị mặc định của bất kỳ loại bằng cách gọi phương pháp này là:

GetDefault<int>(); // 0 
GetDefault<string>(); // null 
GetDefault<DateTime>(); // 01/01/0001 00:00:00 
GetDefault<TimeSpan>(); // 00:00:00 

NET sử dụng Generics trong bộ sưu tập, ... Ví dụ:

List<int> integerList = new List<int>(); 

Bằng cách này bạn sẽ có một danh sách mà chỉ chấp nhận số nguyên, vì lớp được instancited với kiểu T, trong trường hợp này int, và phương pháp mà thêm yếu tố được viết như sau:

public class List<T> : ... 
{ 
    public void Add(T item); 
} 

Một số thông tin khác về generics.

Bạn có thể giới hạn phạm vi loại T.

Ví dụ sau chỉ cho phép bạn gọi phương pháp này với các loại mà các lớp học:

void Foo<T>(T item) where T: class 
{ 
} 

Ví dụ sau chỉ cho phép bạn gọi phương thức với các loại mà Circle hoặc kế thừa từ nó.

void Foo<T>(T item) where T: Circle 
{ 
} 

Và có new() nói rằng bạn có thể tạo một thể hiện của T nếu nó có một constructor parameterless. Trong ví dụ sau T sẽ được coi như Circle, bạn nhận được IntelliSense ...

void Foo<T>(T item) where T: Circle, new() 
{ 
    T newCircle = new T(); 
} 

Như T là một tham số kiểu, bạn có thể nhận được các đối tượng Type từ nó. Với Type bạn có thể sử dụng phản ánh ...

void Foo<T>(T item) where T: class 
{ 
    Type type = typeof(T); 
} 

Như một ví dụ phức tạp hơn, kiểm tra chữ ký của ToDictionary hoặc bất kỳ phương pháp LINQ khác.

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector); 

Không có một T, tuy nhiên có TKeyTSource. Chúng tôi khuyên bạn luôn đặt tên cho các tham số kiểu với tiền tố T như được hiển thị ở trên.

Bạn có thể đặt tên TSomethingFoo nếu muốn.

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