2012-10-26 23 views
7

Tôi có một lớp thuộc loại này:Điều gì sẽ xảy ra nếu T vô hiệu trong Generics? Làm thế nào để bỏ dấu ngoặc nhọn

class A<TResult> 
{ 
    public TResult foo(); 
} 

Nhưng đôi khi tôi cần phải sử dụng lớp này như là một lớp không chung chung, tức là loại TResultvoid.
Tôi không thể nhanh chóng lớp theo cách sau:

var a = new A<void>(); 

Ngoài ra, tôi không muốn chỉ định loại bỏ các dấu ngoặc nhọn:

var a = new A(); 

Tôi không muốn lại viết cả lớp bởi vì nó cũng giống như vậy.

+1

Bạn không thể chỉ sử dụng 'đối tượng'? – Davio

+0

@ Davio vâng, nhưng thật kinh khủng ... – Nick

+3

Trong trường hợp đó, bạn phải tạo một lớp riêng biệt 'A' không có ràng buộc. Nhưng làm thế nào để thực hiện lớp học trông giống như không có T? bạn có phương thức 'T foo()' trên đó. Điều gì cần T trong trường hợp mất hiệu lực? – nawfal

Trả lời

8

void không phải là loại thực trong C#, thậm chí có cấu trúc tương ứng System.Void trong FCL. Tôi sợ bạn cần một phiên bản không phải chung chung ở đây như thế này:

class A 
{ 
    //non generic implementation 
} 

class A<T> : A 
{ 
    //generic implementation 
} 

bạn có thể thấy trong FCL có System.Action/System.Action<T>, thay vì System.Action<void>, cũng như Task thay vì Task<void>.

EDIT Từ CLI specification(ECMA-335):

Các loại sau đây của các loại không thể được sử dụng như các đối số trong instantiations (các loại generic hoặc các phương pháp):

ByRef loại (ví dụ, System.Generic. Bộ sưu tập.List`1 < chuỗi &> là không hợp lệ)

Loại giá trị có chứa các trường có thể trỏ vào t ông Cil thẩm định ngăn xếp (ví dụ: Danh sách < System.RuntimeArgumentHandle>)

void (ví dụ: Danh sách < System.Void> không hợp lệ)

4

Như tôi đã đăng tải trong bình luận của bạn có thể làm cho nó trông tốt bằng cách kế thừa từ lớp generic:

class A:A<object> 
{ 
} 

này ẩn rõ thông số chung chung nhưng lưu ý rằng trong kinh nghiệm của tôi đây là con đường sai để kế thừa lớp học và mỗi khi tôi đã làm điều này tôi hối hận về nó trong khi lớp học của tôi có phức tạp hơn.

+0

thay vào đó tôi có thể tái sử dụng một lớp học với hàng trăm dòng mã, chỉ thêm một vài chục với mẹo này +1 – Nick

1

void chỉ đơn giản là không phải là một loại trong C#, vì vậy bạn không thể có nó như là một tham số kiểu. Nhưng dù sao, có những lúc bạn muốn một chức năng như thể nó là một.

Trong trường hợp này, bạn có thể sử dụng loại thay thế đơn giản, rất có thể là một cấu trúc rất nhỏ, chẳng hạn như System.Reactive.Unit được sử dụng trong Tiện ích mở rộng phản ứng.

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