C# 泛型方法的可重用非泛型方法
我有以下基本接口C# 泛型方法的可重用非泛型方法,c#,generics,interface,C#,Generics,Interface,我有以下基本接口 public interface IHandler{ void Handle(IMessage message); } public interface IHandler<TMessage> : IHandler where TMessage : IMessage{ void Handle(TMessage message); } 以及继承基本接口的通用接口 public interface IHandler{ void Handle(IMessag
public interface IHandler{
void Handle(IMessage message);
}
public interface IHandler<TMessage> : IHandler where TMessage : IMessage{
void Handle(TMessage message);
}
以及继承基本接口的通用接口
public interface IHandler{
void Handle(IMessage message);
}
public interface IHandler<TMessage> : IHandler where TMessage : IMessage{
void Handle(TMessage message);
}
困扰我的是我必须实现Handle(IMessage)
方法的方式,因为在我看来它有很多冗余代码,每次在类上实现新的IHandler
接口时,我都必须扩展该方法
我正在寻找一种更通用的方法来实现
Handle(IMessage)
方法(可能是在处理程序的基类中),但我目前一直在思考如何实现它。合理的方法是明智地使用反射:
var method = this.GetType().GetMethod("Handle", new[] { message.GetType() });
if (method != null) {
method.Invoke(this, new[] { message });
}
如果您这样做太多以至于性能出现问题,您可以缓存测试结果以获得巨大的改进。合理的方法是明智地使用反射:
var method = this.GetType().GetMethod("Handle", new[] { message.GetType() });
if (method != null) {
method.Invoke(this, new[] { message });
}
如果您这样做太多以至于性能出现问题,您可以缓存测试结果以获得巨大改进。您可以使用新的
动态
关键字将过载分辨率移动到DLR:
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
请注意,如果传入的消息对您的类无效,此操作将在运行时失败,并出现RuntimeBinderException
。要避免此异常,可以为所有未知消息类型添加处理程序:
private void Handle(object unknownMessage)
{
// Handle unknown message types here.
}
要在基类中实现
IHandler.Handle
,您需要做更多的工作:
public class BaseHandler : IHandler
{
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
private void Handle<TMessage>(TMessage message) where TMessage : IMessage
{
var handler = this as IHandler<TMessage>;
if(handler == null)
HandleUnknownMessage(message);
else
handler.Handle(message);
}
protected virtual void HandleUnknownMessage(IMessage unknownMessage)
{
// Handle unknown message types here.
}
}
公共类BaseHandler:IHandler
{
void IHandler.Handle(IMessage消息)
{
动态d=消息;
手柄(d);
}
私有无效句柄(TMessage message),其中TMessage:IMessage
{
var handler=此为IHandler;
if(handler==null)
Handleunknown消息(消息);
其他的
handler.Handle(消息);
}
受保护的虚拟无效HandleUnknownMessage(IMessage unknownMessage)
{
//在此处处理未知的消息类型。
}
}
您的特定处理程序将如下所示:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
公共类ExampleHandler:BaseHandler,
伊汉德勒,
伊汉德勒
{
公共无效句柄(例如消息)
{
//在这里处理示例消息
}
公共无效句柄(其他示例消息)
{
//在此处处理其他示例消息
}
}
此代码现在的工作方式如下:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
BaseHandler.Handle
方法和实际的消息类型,即TMessage
将不是IMessage
,而是具体的消息类,如ExampleMessage
HandleUnknownMessage
来处理未知的消息类型Handle
方法,有效地将调用委托给具体的处理程序实现您可以使用新的
dynamic
关键字将过载分辨率移动到DLR:
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
请注意,如果传入的消息对您的类无效,此操作将在运行时失败,并出现RuntimeBinderException
。要避免此异常,可以为所有未知消息类型添加处理程序:
private void Handle(object unknownMessage)
{
// Handle unknown message types here.
}
要在基类中实现
IHandler.Handle
,您需要做更多的工作:
public class BaseHandler : IHandler
{
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
private void Handle<TMessage>(TMessage message) where TMessage : IMessage
{
var handler = this as IHandler<TMessage>;
if(handler == null)
HandleUnknownMessage(message);
else
handler.Handle(message);
}
protected virtual void HandleUnknownMessage(IMessage unknownMessage)
{
// Handle unknown message types here.
}
}
公共类BaseHandler:IHandler
{
void IHandler.Handle(IMessage消息)
{
动态d=消息;
手柄(d);
}
私有无效句柄(TMessage message),其中TMessage:IMessage
{
var handler=此为IHandler;
if(handler==null)
Handleunknown消息(消息);
其他的
handler.Handle(消息);
}
受保护的虚拟无效HandleUnknownMessage(IMessage unknownMessage)
{
//在此处处理未知的消息类型。
}
}
您的特定处理程序将如下所示:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
公共类ExampleHandler:BaseHandler,
伊汉德勒,
伊汉德勒
{
公共无效句柄(例如消息)
{
//在这里处理示例消息
}
公共无效句柄(其他示例消息)
{
//在此处处理其他示例消息
}
}
此代码现在的工作方式如下:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
BaseHandler.Handle
方法和实际的消息类型,即TMessage
将不是IMessage
,而是具体的消息类,如ExampleMessage
HandleUnknownMessage
来处理未知的消息类型Handle
方法,有效地将调用委托给具体的处理程序实现你陷入困境是因为你的班级(在问题中)做了不止一件事。它处理
ExampleMessage
和OtherExampleMessage
。我建议您创建一个类来处理一件事
示例:
public class ExampleHandler : IHandler<ExampleMessage>
public类示例处理程序:IHandler
及
public类OtherExampleHandler:IHandler
根据我的理解,您希望有一个类来处理某种事件。在这种情况下,您可能必须使用通知每个处理程序什么时候发生了什么事情,并让他们做他们的工作。您卡住了,因为您的类(在问题中)做了不止一件事。它处理
ExampleMessage
和OtherExampleMessage
。我建议您创建一个类来处理一件事
示例:
public class ExampleHandler : IHandler<ExampleMessage>
public类示例处理程序:IHandler
及
public类OtherExampleHandler:IHandler