手动您可以做到这一点,但它与转换过程中涉及的反射一样昂贵。一旦委托转换它的行为基本上是相同的......
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);
}
你的解释是伟大的工作,直到我试图用行动。我如何处理Action? (Action formatMessageCallback) 我的方法签名: public void Error –
我不公开Common.Logging委托或任何API,因为我们决定在将来使用不同的日志记录框架。如果发生这种情况,那么我们所要做的就是编写一些代码,这些代码实现了我们之前定义的日志接口,并将这些调用包装到新的日志框架中。 –
@大卫:没有使用记录器的委托的原因是有效的,谢谢解释。请参阅更新以获取您的第一条评论的解决方案。 –