2012-06-04 36 views
7

Tôi có hai hàm sau, gần như giống hệt nhau, khác biệt duy nhất là một hàm sử dụng func, số khác action. Và tôi muốn kết hợp chúng thành một chức năng nếu có thể.C# cách để viết Func với khoảng trống trả về

private static void TryCatch(Action action) 
    { 
     try 
     { 
      action(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

    private static TResult TryCatch<TResult>(Func<TResult> func) 
    { 
     try 
     { 
      return func(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

Trả lời

3

Không thể kết hợp hai hàm này thành một hàm trong C#. Các void trong C#, và CLR, chỉ đơn giản là không phải là một loại và do đó có ngữ nghĩa trở lại khác nhau hơn một chức năng không void. Cách duy nhất để thực hiện đúng mô hình như vậy là cung cấp tình trạng quá tải cho các đại biểu vô hiệu và không có giá trị

Giới hạn CLR không có nghĩa là không thể thực hiện trong mọi ngôn ngữ CLR. Nó chỉ là không thể trong các ngôn ngữ sử dụng void để đại diện cho một hàm không trả về giá trị nào. Mẫu này rất khả thi trong F # vì nó sử dụng Unit thay vì void cho các phương thức không trả về giá trị.

+0

Cảm ơn đã giải thích về lý do tại sao nó không thể. – CaffGeek

4

Bạn có thể sử dụng phiên bản thứ hai, Func<T> để triển khai phương thức Action bằng cách chỉ gói Hành động trong lambda. Điều này giúp loại bỏ một số mã trùng lặp.

private static void TryCatch(Action action) 
{ 
    Func<object> fun => 
     { 
      action(); 
      return null; 
     }; 
    TryCatch(fun); 
} 

đó đang được nói, có overhead thêm tham gia trong việc này, vì vậy cá nhân tôi, tôi có lẽ muốn rời khỏi nó theo cách bạn hiện đang có nó được thực hiện (đặc biệt là đưa ra cách ngắn gọn và đơn giản phiên bản ban đầu của bạn sẽ xảy ra là trong trường hợp này).

+0

+1 Xem câu trả lời của tôi cho một cú pháp thay thế. –

+0

Cảm ơn, như đề nghị tôi sẽ để nó như vậy. Sucks tôi thực sự không thể giảm nó thành một chức năng duy nhất. – CaffGeek

+0

@Chad No - bạn có thể làm cho nó một lớp lót - tôi chia nó thành hai để bạn có thể nhìn thấy/hiểu những gì đang xảy ra, nhưng phương pháp của bạn đủ ngắn tôi để nó như vậy. Không có cách nào để loại bỏ các phương pháp quá tải, mặc dù. –

1

Tôi làm điều này như @ReedCopsey đề xuất.

Đây là cú pháp đơn giản nhất tôi đã tìm thấy:

private static void TryCatch(Action action) 
{ 
    TryCatch(() => { action(); return 0; }); 
} 
+0

Làm thế nào bạn sẽ làm điều này nếu bạn cần phải vượt qua một tham số cho Func? – Nicknow

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