2010-10-23 29 views
10

Tôi muốn tạo một phương thức đơn giản chấp nhận cả hai loại tham số loạitham chiếu, tức là int là giá trị và chuỗi là tham chiếu.Tạo phương thức chung C# có chấp nhận loại giá trị và kiểu tham chiếu có thể (nullable) không?

Vì vậy, đây là những gì tôi bắt đầu với:

public bool areBothNotNull<T>(T? p1, T? p2) 
{ 
    return (p1.HasValue && p2.HasValue); 
} 

Vì vậy, tôi muốn để có thể sử dụng nó như thế này:

var r1 = areBothNotNull<int>(3, 4); // will be true 
var r2 = areBothNotNull<int>(3, null); // will be false 
var r3 = areBothNotNull<string>("three", "four"); // will be true 
var r4 = areBothNotNull<string>(null, "four"); // will be false 

Nhưng vấn đề đầu tiên tôi gặp phải là

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'

Để tiếp tục, tôi thêm ràng buộc struct vào phương pháp của tôi

public bool areBothNotNull<T>(T? p1, T? p2) where T : struct 

Nhưng bây giờ phương pháp này sẽ không chấp nhận chuỗi các cuộc gọi dựa, và mang lại cho tôi lỗi này:

The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method.

Đây có phải là có thể? Hay tại sao chúng ta ngăn cản việc này?

+1

dường như điều lạ lùng muốn làm? –

+5

Điều này không lạ, nó chỉ có mùi ngọt ngào của C++. –

Trả lời

22

Vấn đề của bạn là bạn muốn hạn chế kiểu generic được mâu thuẫn với nhau:

  • Nullable<T> công trình với các loại giá trị chỉ
  • loại tham khảo không kiểu giá trị

Vì vậy, bạn sẽ cần phải có hai tình trạng quá tải để mã của bạn hoạt động:

public static bool areBothNotNull<T>(T? p1, T? p2) where T : struct 
{    
    return (p1.HasValue && p2.HasValue); 
} 

public static bool areBothNotNull<T>(T p1, T p2) 
{ 
    return (p1 != null && p2 != null); 
} 

Tuy nhiên, các dòng sau sẽ không bao giờ biên dịch:

var r3 = areBothNotNull<string>(3, 4); 

Có một mâu thuẫn ở đây, nơi mà các đối số kiểu generic khẳng định rằng các tham số là kiểu string, nhưng mã cố gắng để vượt qua int s để thay thế.

+0

Tôi cũng sẽ thêm nơi T: struct và nơi T: ràng buộc lớp vào phương thức. –

+1

Xin lỗi đó là lỗi sao chép/dán cho dòng R3, tôi sẽ cập nhật câu hỏi, "ba", "bốn" phải là thông số. –

+0

@Sara: liên quan đến sự hiểu biết Nullable , tôi đã viết một bài đăng blog về điều đó một thời gian trước đây: http://softwareblog.alcedo.com/post/2010/02/16/Nullable3cT3e-vs-null.aspx –

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