2011-10-06 28 views
6

Tôi đang thử nghiệm với các phương pháp mở rộng thông thạo.Sử dụng các ràng buộc chung với các loại giá trị

Tôi có phương pháp tiện ích mở rộng đơn giản sau đây để thực hiện dàn diễn viên an toàn.

 public static T As<T>(this Object source) 
     where T : class 
    { 
     return source as T; 
    } 

này làm việc tốt, nhưng khi tôi đã cố gắng để làm cho nó trực quan để sử dụng valuetypes với một tình trạng quá tải

 public static T As<T>(this ValueType source) 
     where T : struct 
    { 
     return (T)source; 
    } 

Tôi chạy vào vấn đề. Logic phân giải phương thức luôn chọn phương thức đầu tiên ở trên và đưa ra lỗi cú pháp (chính xác) là cấu trúc không phải là một lớp.

Có cách nào để xử lý ở trên hay tôi nên đi tuyến đường loại bỏ ràng buộc trong khi thử nghiệm và xử lý tất cả các loại trong cùng một phương pháp?

==== Chỉnh sửa: để trả lời câu hỏi ====

Tôi đang biên dịch điều này dựa trên khung 3.5. Tôi không thực sự cố gắng thực hiện bất cứ điều gì đặc biệt; đây chỉ là một thử nghiệm với những điều trên. Sở thích của tôi đã được đánh giá cao và tôi đã ném cùng một số mã.

Tôi không đặc biệt quan tâm đến việc nó vẫn còn là dàn diễn viên 'an toàn'. Đó là cách nó bắt đầu, và có thể được giữ an toàn với mặc định() - nhưng đó không thực sự là trọng tâm của câu hỏi và mã để đảm bảo 'an toàn' sẽ chỉ mơ hồ.

Đối với tính biểu cảm, không có value.As<int>() không có ý nghĩa nào hơn là (int)value; nhưng tại sao người dùng của phương thức phải 'chỉ biết' nó chỉ hoạt động với các kiểu tham chiếu? Tôi cố gắng để làm việc đó là nhiều hơn về hành vi mong đợi của phương pháp hơn là văn bản biểu cảm.

Đoạn mã value.As<DateTime>(), đưa ra lỗi "Loại 'System.DateTime' phải là loại tham chiếu để sử dụng nó làm tham số 'T' theo kiểu hoặc phương thức chung chung .... Là (đối tượng)" . Từ thông báo lỗi, tôi thấy nó đang giải quyết để sử dụng phương thức hàng đầu ở trên vì nó là phương thức yêu cầu loại tham chiếu.

+0

Phiên bản nào của C# bạn đang sử dụng? Trong .NET 4, quá tải thứ hai được chọn. –

+1

Bạn có nghĩa là mã như 'đối tượng o = 42; var i = o.As (); 'cung cấp lỗi cú pháp? Hoặc bạn có thể hiển thị mã chính xác cung cấp mã đó không? – svick

+0

@ svick của bình luận mang đến cho tâm trí của tôi có lẽ một cái gì đó bạn có thể đang cố gắng để làm với một kết quả cơ sở dữ liệu, như một DataRow, ví dụ. Nếu vậy, một phương thức mở rộng đã sẵn sàng để chuyển đổi giá trị đối tượng trong hàng thành một kiểu thích hợp. [.Field ] (http://msdn.microsoft.com/en-us/library/bb360891.aspx) –

Trả lời

3

Trong .NET 4, quá tải thứ hai được chọn dựa trên mẫu mã của bạn. (Cũng chỉ được thử nghiệm với .NET 3.5, cùng một kết quả.)

int myInt = 1; 
long myLong = myInt.As<long>(); // chooses ValueType version 

Tuy nhiên, điều này chỉ khiến chúng tôi gặp hiện tượng vụ tai nạn tiếp theo. (T)source; dẫn đến ngoại lệ truyền không hợp lệ. Bạn thể được xung quanh đó bằng cách viết phương pháp như

public static T As<T>(this ValueType source) 
    where T : struct 
{ 
    return (T)Convert.ChangeType(source, typeof(T)); 
} 

Tuy nhiên, tôi tự hỏi những gì bạn đang thực sự tìm kiếm để đạt được, như tôi không thấy lợi ích trước mắt. (Và cho rằng vấn đề, đây không phải là an toàn giống như phiên bản source as T đối tượng.) Ví dụ, làm thế nào là

long myLong = myInt.As<long>(); 

Bất kỳ biểu cảm nhiều hơn hoặc dễ dàng hơn để sử dụng hơn

long myLong = (long)myInt; 
+0

Vì ValueType là - mặc dù tên của nó - thực sự là một loại lớp, công thức thứ hai sẽ yêu cầu đấm bốc của tranh luận. Thật không may, tôi thực sự không nghĩ rằng có bất kỳ cách nào để thực hiện. Net cho phép quá tải dựa trên giá trị-loại-Ness của một tham số chung. – supercat

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