2011-07-01 36 views
7

Một trong những lợi ích với các mẫu C++ là bạn (ngầm) có thể yêu cầu một chữ ký kiểu nhất định (ví dụ kiểu T cần có một hàm x không có tham số và trả về một int). C# generics hỗ trợ một cái gì đó tương tự?C# generics có hỗ trợ các ràng buộc chữ ký kiểu không?

Tôi biết về các ràng buộc dựa trên lớp cơ sở hoặc giao diện nhưng đây không phải là những gì tôi đang tìm kiếm.

(Là một C++ lập trình viên học tập C# Tôi có thể bị nhầm lẫn rằng đây là một tính năng mà bạn muốn có trong C#. Bất kỳ ý kiến ​​về vấn đề này sẽ được appriciated cũng ...)

+4

Nhưng ràng buộc giao diện đã là một cách khá tốt để thể hiện một cái gì đó như 'T thực hiện một phương pháp X() phù hợp với một số chữ ký', bạn không nghĩ? –

Trả lời

6

Không có gì ngoại trừ những ràng buộc bạn đã thấy (thực hiện, công bằng, bao gồm rất nhiều kịch bản phổ biến). Có một số cách giải quyết chung:

  • dynamic, trong 4,0
  • tay vịt-gõ bằng cách sử dụng phản ánh hoặc IL thế hệ vv

không ai trong số này đã loại kiểm tra vv, mặc dù tĩnh.

+0

Động có lẽ là gần nhất tôi có thể nhận được. Trong thực tế, tôi thường nghĩ về các mẫu C++ như là một "ngôn ngữ biên dịch thời gian động" (có lẽ là một cụm từ không có ý nghĩa với bất kỳ ai trừ tôi :) –

+0

@Tobias Tôi đã đi với "kiểm tra tĩnh vịt- "; p (' dynamic' có ý nghĩa của thời gian chạy, nhưng tôi biết ý bạn là gì) –

+0

và đột nhiên nó có ý nghĩa với mọi người :) –

0

Có 5 loại trở ngại bạn có thể đặt vào generics trong .Net:

  1. Ràng buộc phái sinh nêu lên mức tăng của tham số kiểu.
  2. Hạn chế giao diện là các giao diện được thực thi bởi thông số loại.
  3. Ràng buộc loại giá trị hạn chế tham số kiểu thành loại giá trị.
  4. Ràng buộc loại tham chiếu hạn chế tham số kiểu cho loại tham chiếu.
  5. Ràng buộc xây dựng quy định rằng tham số kiểu có một hàm tạo mặc định hoặc không có tham số.

This trang hiển thị thêm thông tin.

+0

"Tôi biết về các ràng buộc dựa trên lớp cơ sở hoặc giao diện nhưng đây không phải là những gì tôi đang tìm kiếm". –

4

Có, thông qua giao diện. Bạn có thể định nghĩa một đối tượng chung có một kiểu mà phải có một giao diện cụ thể được triển khai thực hiện. Trong giao diện đó, về cơ bản bạn sẽ buộc phải thêm bất kỳ đối tượng nào vào danh sách chung chung đó, để có một chữ ký cụ thể.

Có hay không đó là những gì bạn đang không phải đang tìm kiếm, đó là cách bạn thực hiện nó. :)

+1

Điều đó vẫn không bao gồm tất cả các tùy chọn, mặc dù - nhà xây dựng với các tham số, toán tử, phương thức tĩnh , vv ... –

+0

@Marc Vâng, không có giải pháp hoàn hảo nào trong tình huống này - giống như bạn đã lưu ý trong câu trả lời của mình. OP sẽ phải uốn cong một chút để hoàn thành nhiệm vụ của mình. Và anh ta có thể không cần bất cứ thứ gì bạn đề cập. Ông muốn lớp chung của mình phù hợp với "hàm x không có tham số và trả về một" –

+0

@Marc, tôi đồng ý, và các ràng buộc hỗ trợ đối với các nhà xây dựng không mặc định sẽ là IMHO tốt đẹp. Những người khác, không quá nhiều, * đặc biệt là * các nhà khai thác :) –

1

No. Đây là những gì interface s cho. Tạo một interface xác định hợp đồng bạn muốn thực thi trong các ràng buộc loại. Sau đó, xác định rằng trong các ràng buộc.

0

Không, không được hỗ trợ trong C#. Như bạn đã nói, điều gần nhất đòi hỏi bạn phải có các lớp thực hiện một giao diện chung.

Bạn có thể cố gắng bắt chước hành vi bằng phản ánh, bằng cách tìm phương pháp theo chữ ký, nhưng đó là ràng buộc thời gian chạy và không phải là ràng buộc thời gian biên dịch.

0

Không, C# không có ràng buộc như vậy.Như bạn đã biết, các ràng buộc chung chỉ có thể thực thi thừa kế của một lớp cơ sở hoặc một giao diện, hoặc một vài ràng buộc khác (ràng buộc constructor new(), ràng buộc kiểu tham chiếu class, ràng buộc kiểu giá trị struct).

Bạn có thể đạt được hành vi mong muốn của mình bằng cách sử dụng đại biểu và có nhiều đại biểu chung có sẵn.
Ví dụ: Func<int> là đại biểu không có tham số và trả lại int. Func<string, DateTime, int> mất một số stringDateTime và trả về số int, v.v ...

3

Không, điều này là không thể. Nó chủ yếu là do sự khác biệt giữa các mẫu C++ và C# generics:

Khi bạn biên dịch mẫu C++, mã kết quả có các loại như vector<int>vector<string>. Điều này có nghĩa là trình biên dịch phải biết tất cả các tham số kiểu có thể, nhưng nó cũng có nghĩa là nó có thể kiểm tra chúng đúng đắn.

Khi bạn biên dịch loại C# chung, bạn thực sự chỉ tạo một loại chung: List<T>. Bởi vì điều này, trình biên dịch C# không phải biết tất cả các loại có thể ở dạng biên dịch, có nghĩa là bạn có thể có các kiểu generic trong các thư viện nhị phân, điều này là không thể với C++. Nhưng điều này cũng có nghĩa là bạn không thể kiểm tra tất cả các loại. Để có thể làm điều gì đó như vậy, có những ràng buộc, nhưng họ không thể thực hiện một số việc kiểm tra thời gian biên dịch của C++, như kiểm tra sự hiện diện của các phương thức nhất định (không sử dụng giao diện hoặc một số lớp cơ sở) hoặc sự hiện diện của các toán tử thích hợp.

Trong C# 4, bạn có thể đạt được hiệu quả tương tự như loại mẫu sử dụng dynamic, nhưng điều này không không kiểm tra thời gian biên dịch, có nghĩa là bạn bị mất an toàn - bạn có thể đặt trong một loại mà không có các thành viên thích hợp và bạn sẽ không tìm ra cho đến khi bạn đạt đến dòng mã đó khi chạy.

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