我有以下基本接口(interface)
public interface IHandler{
void Handle(IMessage message);
}
以及继承基接口(interface)的通用接口(interface)
public interface IHandler<TMessage> : IHandler where TMessage : IMessage{
void Handle(TMessage message);
}
我的类可以实现接口(interface)IHandler<TMessage>
多次。 IMessage
是消息的基本接口(interface),与此处无关。目前我正在实现如下接口(interface)。
public class ExampleHandler : IHandler<ExampleMessage>, IHandler<OtherExampleMessag>{
void IHandler.Handle(IMessage message){
ExampleMessage example = message as ExampleMessage;
if (example != null) {
Handle(example);
}
else {
OtherExampleMessage otherExample = message as OtherExampleMessage;
if (otherExample != null) {
Handle(otherExample);
}
}
public void Handle(ExampleMessage) {
//handle message;
}
public void Handle(OtherExampleMessage) {
//handle message;
}
}
令我困扰的是我必须实现 Handle(IMessage)
的方式方法,因为在我看来它有很多冗余代码,并且每次当我实现新的IHandler<TMessage>
时我都必须扩展该方法。我的类(class)界面。
我正在寻找的是一种更通用的方法来实现 Handle(IMessage)
方法(可能在处理程序的基类中),但我目前不知道如何做到这一点。
最佳答案
您可以使用新的 dynamic
关键字将重载决策移至 DLR:
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
请注意,这将在运行时失败,并显示 RuntimeBinderException
如果传入的消息对您的类(class)无效。
为了避免这种异常,您可以为所有未知消息类型添加处理程序:
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.
}
}
您的特定处理程序将如下所示:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
此代码现在的工作方式如下:
- DLR 调用通用
BaseHandler.Handle<TMessage>
具有真实消息类型的方法,即TMessage
不会IMessage
但具体的消息类如ExampleMessage
. - 在此通用处理程序方法中,基类尝试将自身设置为特定消息的处理程序。
- 如果不成功,则会调用
HandleUnknownMessage
处理未知的消息类型。 - 如果转换成功,它会调用
Handle
特定消息处理程序上的方法,有效地将调用委托(delegate)给具体的处理程序实现。
关于c# - 泛型方法的可重用非泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12855930/