2011-01-19 9 views

Trả lời

11

Nó cho phép bạn sử dụng toán tử as trên T nếu đó là T:class.

Nó cấm bạn so sánh T với null nếu T là T:struct.

Lưu ý rằng nếu bạn bỏ qua T:class thì bạn có thể so sánh T thành null ngay cả khi T là một loại giá trị.

[Lưu ý: Tôi cần chỉnh sửa bài đăng này vài lần trước khi bài đăng chính xác. Ít nhất tôi hy vọng nó bây giờ là chính xác.]

-1

"T: class" sẽ buộc loại chung được chỉ định là một lớp, không phải là một giá trị. Ví dụ, chúng ta có thể tạo nên một lớp ObjectList đòi hỏi kiểu generic quy định để trở thành một lớp, không phải là một giá trị:

class ObjectList<T> where T : class { 
    ... 
} 

class SomeObject { ... } 

ObjectList<int> invalidList = new ObjectList<int>(); //compiler error 

ObjectList<SomeObject> someObjectList = new ObjectList<SomeObject>(); //this works 

Điều này buộc một bất biến vào loại T generic của bạn mà nếu không có thể không được thực thi. "T: struct" sẽ hoạt động theo cùng một cách. Lưu ý rằng bạn cũng có thể sử dụng cấu trúc này để thực thi không chỉ loại T là một lớp, mà còn là nó khớp với một giao diện. Mẫu mã tôi lấy từ đây cũng có

class MyList<T> where T : class, IEntity { ... } 

buộc T là một lớp VÀ cũng là một IEntity.

+0

Cảm ơn bạn , nhưng tôi nhận thức được ngữ nghĩa của các ràng buộc chung - những gì tôi yêu cầu là các ví dụ trong đó các ràng buộc struct/class là * useful *. – Oak

1

Tính hữu ích chính mà tôi đã tìm thấy trong nó nằm với Marshalling và ghim đối tượng vào bộ nhớ.

Ví dụ, tôi làm rất nhiều công việc với cấu trúc nội bộ mà không thể được tự động chuyển đổi, hoặc được gửi xuống các dây như một dòng byte, vì vậy tôi đã viết helper này:

public static T PinAndCast<T>(this Array o) where T : struct 
{ 
    var handle = System.Runtime.InteropServices.GCHandle.Alloc(o, GCHandleType.Pinned); 
    T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 
    handle.Free(); 
    return result; 
} 
+0

Tôi nghĩ rằng việc tạo ra các cá thể mới phụ thuộc vào các ràng buộc "T: new()", không phụ thuộc vào ràng buộc lớp/struct? Ngoài ra, tôi không thực sự quen thuộc với Marshalling và bộ nhớ-pinning trong C#, có lẽ bạn có thể cung cấp một ví dụ mã? – Oak

+0

Tất cả phụ thuộc vào các chi tiết cụ thể. Trong trường hợp của tôi, tôi cần chuyển đổi một tập các byte hiện có thành một cấu trúc. Tuy nhiên, việc tạo các cá thể mới, cụ thể, không phụ thuộc vào ràng buộc mới(). Tôi đã chỉnh sửa phản hồi của tôi để phản ánh điều này. –