2011-08-17 26 views
12

Có thể chỉ định ràng buộc trên một lớp chung không cho phép một số loại nhất định không? Tôi không biết nếu nó là có thể và nếu có, tôi không chắc chắn cú pháp sẽ là gì. Một cái gì đó như:Làm thế nào để xác định các loại không được phép trong một hạn chế NET Generics?

public class Blah<T> where : !string { 
} 

Tôi dường như không tìm thấy bất kỳ ký hiệu nào cho phép hạn chế như vậy.

+0

không nghĩ rằng điều này là có thể - nhưng tại sao bạn sẽ cần một cái gì đó như thế này? – Carsten

+0

Hành vi mong muốn khi ai đó cố gắng chuyển sang loại không được hỗ trợ? –

+0

Tôi thực sự đã cố gắng để loại trừ các loại chuỗi, nhưng nó chỉ ra rằng bằng cách sử dụng nơi T: struct làm việc cho những gì tôi đang cố gắng làm kể từ lớp của tôi sẽ không làm việc cho các loại phức tạp anyways. –

Trả lời

11

Gần nhất bạn có thể nhận được là hạn chế thời gian chạy.

Chỉnh sửa: Ban đầu tôi đặt kiểm tra thời gian chạy trong lệnh gọi hàm tạo. Đó thực sự không phải là tối ưu, vì nó phải gánh chịu mọi chi phí trên mọi instantiation; Tôi tin rằng nó sẽ được nhiều hơn nữa hợp lý để đặt dấu check ở mục tĩnh constructor, mà sẽ được gọi một lần cho mỗi loại sử dụng làm tham số T cho loại Blah<T> của bạn:

public class Blah<T> { 
    static Blah() { 
     // This code will only run ONCE per T, rather than every time 
     // you call new Blah<T>() even for valid non-string type Ts 
     if (typeof(T) == typeof(string)) { 
      throw new NotSupportedException("The 'string' type argument is not supported."); 
     } 
    } 
} 

Rõ ràng không lý tưởng, nhưng nếu bạn đặt ràng buộc này vào vị trí ghi lại thực tế là string không phải là đối số kiểu được hỗ trợ (ví dụ: thông qua nhận xét XML), bạn sẽ nhận được ở đâu đó gần hiệu quả của ràng buộc biên dịch.

+1

thường tôi đặt các ràng buộc không thể diễn tả trong C# vào constructor lớp. – CodesInChaos

+0

Để bao gồm loại có thể được giải quyết dưới dạng chuỗi: if (typeof (string) .IsAssignableFrom (typeof (T))) ném NotSupportedException mới – Rasmus

4

Không, bạn không thể xác định trực tiếp các hạn chế loại "phủ định".

+0

Có phương pháp gián tiếp nào khác, giống như khẳng định rằng typeof (T) không phải là một cái gì đó? – SirPentor

+0

@SirPentor Không phải là một phần của ràng buộc kiểu, mặc dù bạn có thể làm điều gì đó tương tự như vậy trong mã. – Donut

2

Ràng buộc chỉ có thể là những hạn chế tích cực, như được nêu trong documentation.

Điều duy nhất bạn có thể làm là xác định những loại thể được đưa vào các loại chung chung, nhưng bạn không thể xác định những gì không thể được đưa vào chúng.

1

Dưới đây là những hạn chế cho phép (more detail)

  • nơi T: struct
  • nơi T: lớp
  • nơi T: new()
  • nơi T: [tên lớp cơ sở]
  • trong đó T: [tên giao diện]
  • trong đó T: U (Đối số kiểu được cung cấp cho T phải là hoặc lấy được từ đối số được cung cấp cho U)
Các vấn đề liên quan