2011-07-05 3 views
8

Chúng tôi đang sử dụng IoC và có đăng nhập của chúng tôi tiếp xúc với nó. Chúng tôi đang sử dụng Common.Logging và tôi đã viết một đại biểu phù hợp cho Common.Logging.FormatMessageHandler nhưng tôi không biết cách chuyển đổi từ phiên bản của đại biểu đó sang phiên bản mà Common.Logging api đang chờ.Chuyển đổi từ một đại biểu này sang đại biểu khác. Pseudo cast

Câu hỏi này có vẻ tương tự nhưng tôi không hiểu cách chuyển đổi từ loại đã triển khai sang loại đã biết mà tôi muốn gọi. Dynamically casting one type of delegate to another

Đây là chữ ký của tôi đại biểu:

public delegate string FormatMessageHandler(string format, params object[] args) 

Đây là Common.Logging của:

public delegate string FormatMessageHandler(string format, params object[] args) 

Cùng tên (không có nghĩa là vấn đề) và cùng một số thông số. Cả hai đều được biết tại thời gian biên dịch nên nó phải là một cái gì đó hiển nhiên nhưng tôi không nhìn thấy nó.

Trả lời

7

Tại sao bạn không sử dụng đại biểu Common.Logging ở nơi đầu tiên nếu nó giống hệt nhau?
Tuy nhiên, một solition cho vấn đề của bạn là để thể sử dụng các diễn viên năng động giới thiệu trong phần liên kết trong câu hỏi mà bạn đề cập, hoặc bạn làm điều đó như thế này:

YourNamespace.FormatMessageHandler yourHandler = ...; 
Common.Logging.FormatMessageHandler handler = (f, a) => yourHandler(f, a); 

UPDATE:
Theo bạn nhận xét, bạn muốn một cái gì đó như thế:

public void Error(Action<Your.FormatMessageHandler> formatMessageCallback) 
{ 
    _logger.Error(h => formatMessageCallback((f, a) => h(f, a))); 
} 

này sẽ tạo ra một hành động mới với một tham số h loại Common.Logging.FormatMessageHandler trong đó kêu gọi hành động cung cấp 0.123.với một đại biểu mới của Your.FormatMessageHandler chấp nhận hai thông số fa. Đại biểu mới này lần lượt gọi h với hai tham số được cung cấp.

+0

Giải thích của bạn rất tuyệt vời và hoạt động cho đến khi tôi cố gắng sử dụng Hành động . Làm thế nào tôi có thể làm với hành động? Chữ ký phương thức của tôi: Lỗi void công khai (Hành động formatMessageCallback) Và phương thức cuối cùng để gọi là: void Common.Logging.Error (Action formatMessageCallback); –

+0

Tôi không trưng bày đại biểu Common.Logging hoặc bất kỳ trường hợp API nào mà chúng tôi quyết định sử dụng khung đăng nhập khác trong tương lai. Nếu điều đó xảy ra thì "tất cả" chúng ta phải làm là viết một số mã thực hiện giao diện ghi nhật ký mà chúng ta đã định nghĩa trước và bọc các cuộc gọi đến khung công tác ghi mới. –

+0

@David: Lý do không sử dụng đại biểu của Logger là hợp lệ, cảm ơn vì đã giải thích. Vui lòng xem cập nhật cho giải pháp cho nhận xét đầu tiên của bạn. –

1

Theo cách thủ công, bạn có thể thực hiện việc này, nhưng tốn kém như sự phản ánh liên quan đến chuyển đổi. Khi đại biểu được chuyển đổi, nó hoạt động về cơ bản giống nhau ...

internal class Program 
{ 
    //An example delegate target 
    static void Click(object o, EventArgs e) { } 

    //A simple test method 
    static void Main(string[] args) 
    { 
     EventHandler onclick = Click; 
     EventHandler<EventArgs> converted; 
     if (!TryConvertDelegate(onclick, out converted)) 
      throw new Exception("failed"); 
    } 

    //The conversion of one delegate type to another 
    static bool TryConvertDelegate<TOldType, TNewType>(TOldType oldDelegate, out TNewType newDelegate) 
     where TOldType : class, System.ICloneable, System.Runtime.Serialization.ISerializable 
     where TNewType : class, System.ICloneable, System.Runtime.Serialization.ISerializable 
    { 
     if (!typeof(Delegate).IsAssignableFrom(typeof(TOldType)) || !typeof(Delegate).IsAssignableFrom(typeof(TNewType))) 
      throw new ArgumentException(); //one of the types is not a delegate 

     newDelegate = default(TNewType); 
     Delegate handler = oldDelegate as System.Delegate; 
     if (handler == null) 
      return true; //null in, null out 

     Delegate result = null; 
     foreach (Delegate d in handler.GetInvocationList()) 
     { 
      object copy = System.Delegate.CreateDelegate(typeof(TNewType), d.Target, d.Method, false); 
      if (copy == null) 
       return false; // one or more can not be converted 
      result = System.Delegate.Combine(result, (System.Delegate)copy); 
     } 
     newDelegate = result as TNewType; 
     return (newDelegate != null); 
    }