我们正在使用IoC并使用它公开我们的日志记录。我们正在使用Common.Logging
,我为Common.Logging.FormatMessageHandler
编写了一个匹配的委托,但我不知道如何将该委托的版本转换为Common.Logging
api期望的版本。< / p>
这个问题似乎很相似,但我不明白如何从我的实现类型转换为我想要调用的已知类型。 Dynamically casting one type of delegate to another
这是我的代表签名:
public delegate string FormatMessageHandler(string format, params object[] args)
这是Common.Logging的:
public delegate string FormatMessageHandler(string format, params object[] args)
相同的名称(不重要)和相同数量的参数。两者在编译时都是已知的,所以它应该是明显的,但我没有看到它。
答案 0 :(得分:8)
如果它完全相同,你为什么不首先使用Common.Logging的委托呢? 但是,解决问题的方法是使用您提到的问题中链接的文章中解释的动态强制转换,或者您这样做:
YourNamespace.FormatMessageHandler yourHandler = ...;
Common.Logging.FormatMessageHandler handler = (f, a) => yourHandler(f, a);
<强>更新强>
根据你的评论,你想要这样的东西:
public void Error(Action<Your.FormatMessageHandler> formatMessageCallback)
{
_logger.Error(h => formatMessageCallback((f, a) => h(f, a)));
}
这将使用h
类型的Common.Logging.FormatMessageHandler
参数创建一个新操作,该参数使用formatMessageCallback
的新委托调用提供的操作Your.FormatMessageHandler
,该委托接受两个参数{{ 1}}和f
。这个新代表依次使用提供的两个参数调用a
。
答案 1 :(得分:1)
手动你可以做到这一点,但它与转换时所涉及的反射一样昂贵。委托转换后,它的行为基本相同......
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);
}