2012-05-17 11 views
14

Khi tôi hạn chế T với: Object như thế này:C# Generics: Ràng buộc T trong đó T: Object không biên dịch; Lỗi: Hạn chế không thể đặc biệt lớp 'đối tượng'

public interface IDoWork<T> where T : Object 
{ 
    T DoWork(); 
} 

tôi nhận được lỗi:

Constraint cannot be special class 'object'

Liệu đó có nghĩa là có một sự khác biệt ngụ ý với sau đây mà biên dịch?

public interface IDoWork<T> // where T : Object 
{ 
    T DoWork(); 
} 
+7

Tất cả các lớp C# là lớp con của đối tượng. Một hạn chế như vậy là hơi lạ một chút :) –

+0

Đối với những gì nó có giá trị, tôi đã cố gắng để làm cho T == Object == Void như trong câu hỏi SO này: http: // stackoverflow.com/q/10644495/328397 – LamonteCristo

+2

ràng buộc này sẽ là thừa, vì đây là mặc định ... –

Trả lời

14

Không có sự khác biệt giữa hai ràng buộc, ngoại trừ trường hợp đó không được phép sử dụng một cách rõ ràng.

C# 4.0 ngôn ngữ đặc tả (10.1.5 trở ngại Loại tham số) cho biết hai điều về điều này:

The type must not be object. Because all types derive from object, such a constraint would have no effect if it were permitted.

...

If T has no primary constraints or type parameter constraints, its effective base class is object.

Trong bình luận của bạn, bạn nói rằng bạn đang cố gắng để làm T là kiểu Void. Void là một loại đặc biệt cho biết không có loại trả lại và không thể được sử dụng thay cho T, yêu cầu loại bê tông thích hợp. Bạn sẽ phải tạo phiên bản trống của phương thức và phiên bản T nếu bạn muốn cả hai.

+1

+1: Điều này giải quyết ý định của OP. – Douglas

+0

Còn cấu trúc thì sao? Tôi đã thử điều này để không cho phép một tấn những thứ không vô giá trị như 'int'. – Nyerguds

42

Nếu bạn muốn hạn chế loại chung làm loại tham chiếu, hãy sử dụng : class.

public interface IDoWork<T> where T : class 
{ 
    T DoWork(); 
} 

Điều này sẽ cấm loại chung loại là loại giá trị, chẳng hạn như int hoặc cấu trúc.

+4

Tôi không biết giao diện được sử dụng cho điều gì, nhưng có vẻ lạ khi cấm các loại giá trị ... một tác vụ trả về int hoặc bool là khá phổ biến. –

+2

Điểm của bạn hợp lệ, nhưng tôi cũng không biết ý định của OP là gì. Tôi cho rằng ': Object' có nghĩa là họ đang cố gắng hạn chế các kiểu tham chiếu. – Douglas

+2

@ThomasLevesque: Có nhiều trường hợp mã chung sẽ hoạt động với bất kỳ loại tham chiếu nào, nhưng không thể làm việc với bất kỳ loại giá trị chung nào; một ví dụ đơn giản sẽ là bất kỳ mã nào sử dụng 'Interlocked.CompareExchange' hoặc sử dụng các lớp chung chung khác làm như vậy. Ràng buộc 'struct' không hoàn toàn hữu ích, mặc dù nó cho phép một kiểu được sử dụng như một' Nullable '. Ngoài ra, có những tình huống mà các loại giá trị thực hiện một giao diện "đúng" có thể hoạt động, nhưng các lớp thực hiện giao diện không thể hoạt động được. – supercat

0

Theo C# 4.0 Language Specification (Coded: [10.1.5] Gõ hạn chế tham số) cho hai điều:

1] The type must not be object. Because all types derive from object, such a constraint would have no effect if it were permitted.

2] If T has no primary constraints or type parameter constraints, its effective base class is object.

Khi bạn định nghĩa một lớp chung, bạn có thể áp dụng hạn chế đối với các loại định dạng mà mã máy khách có thể sử dụng cho các đối số kiểu khi nó khởi tạo lớp của bạn. Nếu mã máy khách cố gắng khởi tạo lớp của bạn bằng cách sử dụng một kiểu không được ràng buộc bởi một ràng buộc, kết quả là một lỗi thời gian biên dịch. Những hạn chế này được gọi là những ràng buộc. Các ràng buộc được xác định bằng cách sử dụng từ khóa theo ngữ cảnh ở đâu. Nếu bạn muốn hạn chế loại chung để trở thành kiểu tham chiếu, hãy sử dụng: class.

Theo MSDN

Hạn chế không thể đặc biệt lớp 'nhận dạng'. Các loại sau đây có thể không được sử dụng như những hạn chế:

  • System.Object
  • System.Array
  • System.Delegate
  • System.Enum
  • System.ValueType.
+0

Câu trả lời này sẽ hữu ích nếu nó giải thích * tại sao * những điều này không có ý nghĩa như những ràng buộc và phải làm gì thay thế. Tôi không có câu trả lời cho các câu hỏi như vậy, nhưng đây là một liên kết khác có nhiều thảo luận về các ràng buộc: https://msdn.microsoft.com/en-us/library/d5x73970.aspx – ToolmakerSteve

+0

@ToolmakerSteve Tôi đã xây dựng câu trả lời của mình một chút. –