2013-03-14 38 views
31

Tôi đã gặp một đại biểu xinh đẹp Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> trong C# .NET 4.5 ngay hôm nay. Tôi giả định 16 là một nơi tùy ý để dừng lại (phương thức nào có hơn 16 tham số?) Nhưng nó khiến tôi suy nghĩ: là có thể trong C# để xác định rằng một kiểu generic có thể có bất kỳ số đối số kiểu nào không? theo cách tương tự mà từ khóa params cho các phương thức cho phép bất kỳ số đối số nào cho một phương thức. Một cái gì đó như thế này:Sử dụng từ khóa "params" cho các tham số chung trong C#

public class MyInfiniteGenericType<params T[]> { ... } 

nơi bên trong lớp sau đó bạn có thể truy cập vào các đối số loại bằng cách liệt kê qua chúng hoặc sử dụng T[index] trong cùng một cách mà params phép trong phương pháp.

Tôi chưa từng sử dụng cá nhân này, nhưng đại biểu Func sẽ là nơi hoàn hảo để sử dụng nó. Sẽ không cần đến 16 loại Func khác nhau!

Vì vậy, câu hỏi của tôi là, điều này có thể được thực hiện theo bất kỳ cách nào trong C# và nếu không phải là ý tưởng ngớ ngẩn này?

+0

Thảo luận liên tục ở nơi khác trên SO: http://stackoverflow.com/a/4046525/63225 – sblom

Trả lời

29

là có thể trong C# để xác định loại chung có thể có bất kỳ số đối số kiểu nào không?

Không, C# không có bất kỳ điều gì giống như tôi sợ.

Về cơ bản Func<T>Func<T1, T2> là các loại hoàn toàn không liên quan đến mức CLR có liên quan và không có gì giống như params để chỉ định nhiều đối số loại.

Đối với tiện ích của nó: Tôi có thể thấy các trường hợp hữu ích, nhưng tôi nghi ngờ chúng đủ hiếm để có nghĩa là đối tượng địa lý không vượt qua ngưỡng "lợi ích/chi phí". (Lưu ý rằng nó gần như chắc chắn sẽ yêu cầu thay đổi CLR quá.)

+2

Tôi đã gặp phải một trường hợp cho điều này ngày hôm nay và đang tìm xem liệu điều đó có khả thi hay không. Tôi không tin một cái gì đó như thế này nên bỏ qua vì chi phí/lợi ích. Tôi có nghĩa là một phương pháp loại 16 chung chung là xấu xí ... và tôi sẵn sàng đặt cược hầu như không có ai đang sử dụng nó, vì vậy thời gian nướng nó vào khuôn khổ là một sự lãng phí. –

+2

@rushonerok: Chi phí đưa vào khung công tác rất thấp và trong khi nó sẽ không được sử dụng bởi mã * manual *, nó được sử dụng để nhập động. Chi phí thay đổi ngôn ngữ để hỗ trợ yêu cầu tính năng này cao hơn rất nhiều. –

2

Không, không thể có số lượng đối số chung tùy ý. Nó có lẽ cũng là một ý tưởng ngớ ngẩn, bởi vì các tham số kiểu generic không được giải quyết trong thời gian chạy, chúng được giải quyết tại thời gian biên dịch, và vì vậy việc lặp lại chúng như thế không phải là điều hiển nhiên.

Bạn cũng có thể nghĩ rằng Tuple < ,,,,,,,,> có thể là một địa điểm rõ ràng cho nó, nhưng giải pháp có khi bạn chạy khỏi đối số chung, bạn làm cho người cuối cùng là Tuple <, ,,,> cho các trường còn lại.

7

C++ 11 có tính năng mà bạn đang nói đến. Họ gọi nó là variadic templates.

C# generics không hoàn toàn giống như các mẫu C++, mặc dù vậy, và sẽ gây khó khăn cho việc xây dựng một điều tương tự.

Trong trường hợp C++, các mẫu được mở rộng tại thời gian biên dịch thành bất kỳ loại cụ thể nào được sử dụng. Trong trường hợp C#, đặc tả loại xảy ra hoàn toàn trong thời gian chạy. Và kết quả IL sẽ cần phải hỗ trợ số lượng các loại khác nhau gặp phải.

1

Không, điều này không thể thực hiện được.

Nó không đơn giản như xử lý nó như là một mảng các loại (một khái niệm mà thậm chí không tồn tại trong C#). Hãy xem xét Func - số tham số kiểu phải giống với số tham số của phương thức Invoke của đại biểu. Nhưng lập trình viên sẽ thể hiện mối quan hệ như thế nào giữa các tham số kiểu và các tham số thông thường?

Tuy nhiên, tính năng này không tồn tại trong C++ 11 - variadic templates. Lưu ý rằng C++ không cho phép truy cập vào các tham số kiểu cá nhân bằng cách sử dụng cú pháp mảng - thay vào đó, các hàm thường tách tham số kiểu đầu tiên khỏi phần còn lại và sử dụng các cuộc gọi đệ quy để giải nén phần còn lại.

0

Tôi chỉ thấy mình tò mò muốn xem liệu có ai khác đã sử dụng nó không. Tôi vừa viết một nhà soạn nhạc chung để xây dựng các vật liệu tổng hợp từ mixin được lắp ráp bằng cách sử dụng Castle Dynamic Proxy.

tôi đã xây dựng nhà soạn nhạc để hỗ trợ hai mixins và sắp sửa tiến hành trên "sao chép và dán và điều chỉnh (bleh)" hai nhà soạn nhạc mixin vào hơn 15 biến thể lên đến 17 trộn nhà soạn nhạc (tương tự như Func<T> qua Func<T1...T16, T>). Nhưng sau đó tôi nghĩ, nó sẽ không tuyệt vời nếu tôi chỉ có thể xác định Composer<TComposer, TIComposite, params[] TIMixin>!

Đáng buồn thay, tôi tắt để sao chép và dán và điều chỉnh (hoạt động rất phổ biến giúp chúng tôi tránh).

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