この動的二重ディスパッチの例を C#に移植しようとしています。私は動作する例を持っていますが、リフレクションを使用して必要なハンドラーを作成し、適切なメソッドを呼び出すことDynamicDispatch
で、クラス内のメソッドを少しショートカットしたように感じます。MessageBase
変更方法についてアドバイスをいただけますか?この例では C++ の dynamic_cast 演算子を使用していますが、C# の同等の演算子が何であるかはわかりません。私の解決策が正しい/最善の方法であるかどうかはわかりません。
注: 3.5 を使用しているため、dynamic キーワードを使用できません
コードは次のとおりです。
メッセージ
public interface IMessage
{
void Dispatch(IHandler handler);
}
MessageBase
public abstract class MessageBase : IMessage
{
public abstract void Dispatch(IHandler handler);
// This is my concern, doesnt feel like the right way to do this
protected void DynamicDispatch<MessageType>(IHandler handler, MessageType self)
{
// Get the messages derived type
Type self_type = self.GetType();
// Create actual message specific handler
Type message_handler = typeof(IMessageHandler<>).MakeGenericType(self_type);
// Get the ProcessMessage method
MethodInfo minfo = message_handler.GetMethod("ProcessMessage");
try
{
// Invoke it with the message
minfo.Invoke(handler, new object[] { self });
}
catch (TargetException ex)
{
// Ignore if method doesnt exist
}
}
}
メッセージ
public class Message : MessageBase
{
public override void Dispatch(IHandler handler)
{
DynamicDispatch(handler, this);
}
}
IHandler
public interface IHandler
{
}
IMessageHandler
public interface IMessageHandler<MessageType> : IHandler
{
void ProcessMessage(MessageType message);
}
DerivedMessageOne
public class DerivedMessageOne : Message
{
public int MessageOneField;
}
派生メッセージ 2
public class DerivedMessageTwo : Message
{
public int MessageTwoField;
}
DerivedMessageHandlerOne
public class DerivedMessageHandlerOne : IMessageHandler<DerivedMessageOne>,
IMessageHandler<DerivedMessageTwo>
{
#region IMessageHandler<MessaegType> Members
// ************ handle both messages *************** //
public void ProcessMessage(DerivedMessageOne message)
{
// Received Message one, do soemthing with i
int do_something_with_it = message.MessageOneField;
}
public void ProcessMessage(DerivedMessageTwo message)
{
// Received Message two, do soemthing with i
}
#endregion
}
DerivedMessageHandlerTwo
public class DerivedMessageHandlerTwo : IMessageHandler<DerivedMessageOne>
{
#region IMessageHandler<MessaegType> Members
// ************ handle just MessageOne *************** //
public void ProcessMessage(DerivedMessageOne message)
{
// Received Message one, do soemthing with i
}
#endregion
}
テストケース
IMessage messageOne = new DerivedMessageOne();
IMessage messageTwo = new DerivedMessageTwo();
IHandler handlerOne = new DerivedMessageHandlerOne();
IHandler handlerTwo = new DerivedMessageHandlerTwo();
messageOne.Dispatch(handlerOne);
messageOne.Dispatch(handlerTwo);
messageTwo.Dispatch(handlerOne);
messageTwo.Dispatch(handlerTwo);