设计帮助 - 多态事件处理

SwD*_*n81 5 c# messaging events event-handling

设计问题 - 多态事件处理

我目前正在尝试减少当前项目中的事件句柄数量.我们有多个通过USB发送数据的系统.我目前有一个例程来读取消息并解析初始标头详细信息以确定消息来自哪个系统.标题稍有不同,所以我创建的EventArgs不一样.然后我通知所有"观察员"这一变化.所以我现在所拥有的是以下内容:

public enum Sub1Enums : byte
{
    ID1 = 0x01,
    ID2 = 0x02
}

public enum Sub2Enums : ushort
{
    ID1 = 0xFFFE,
    ID2 = 0xFFFF
}

public class MyEvent1Args
{
    public Sub1Enums MessageID;
    public byte[] Data;
    public MyEvent1Args(Sub1Enums sub1Enum, byte[] data)
    {
        MessageID = sub1Enum;
        Data = data;
    }
}

public class MyEvent2Args
{
    public Sub2Enums MessageID;
    public byte[] Data;
    public MyEvent2Args(Sub2Enums sub2Enum, byte[] data)
    {
        MessageID = sub2Enum;
        Data = data;
    }
}
Run Code Online (Sandbox Code Playgroud)

Form1代码

public class Form1
{
    public delegate void TestHandlerCurrentlyDoing(MyEvent1Args eventArgs1);
    public delegate void TestHandlerCurrentlyDoingAlso(MyEvent2Args eventArgs2);

    public event TestHandlerCurrentlyDoing mEventArgs1;
    public event TestHandlerCurrentlyDoingAlso mEventArgs2;

    public Form1()
    {
        mEventArgs1 += new TestHandlerCurrentlyDoing(Form1_mEventArgs1);
        mEventArgs2 += new TestHandlerCurrentlyDoingAlso(Form1_mEventArgs2);
    }

    void Form1_mEventArgs2(MyEvent2Args eventArgs2)
    {
        // Do stuff here
        Sub2Enums mid = my_event2_args.MessageID;
        byte[] data = my_event2_args.Data;
    }

    void Form1_mEventArgs1(MyEvent1Args eventArgs1)
    {
        // Do stuff here
        Sub1Enums mid = my_event1_args.MessageID;
        byte[] data = my_event1_args.Data;
    }
Run Code Online (Sandbox Code Playgroud)

在解析算法中我根据它是什么消息:

void ParseStuff()
{
    if (mEventArgs1 != null)
    {
        mEventArgs1(new MyEvent1Args(Sub1Enums.ID1, new byte[] { 0x01 }));
    }
    if (mEventArgs2 != null)
    {
        mEventArgs2(new MyEvent2Args(Sub2Enums.ID2, new byte[] { 0x02 }));
    }
}
Run Code Online (Sandbox Code Playgroud)

我真正想做的是:

public class Form1
{
    public delegate void TestHandlerDesired(MyEvent1Args eventArgs1);
    public delegate void TestHandlerDesired(MyEvent2Args eventArgs2);

    public event TestHandlerDesired mEventArgs;

    public Form1()
    {
        mEventArgs += new TestHandlerDesired (Form1_mEventArgs1);
        mEventArgs += new TestHandlerDesired (Form1_mEventArgs2);
    }
}
Run Code Online (Sandbox Code Playgroud)

出于含糊不清的原因,我们不能这样做.所以我的问题是如何更好地解决这个问题呢?

SwD*_*n81 1

我可以使 MyEvent1Args 和 MyEvent2Args 派生自公共基类并执行以下操作:

\n\n
public class BaseEventArgs : EventArgs\n{\n    public byte[] Data;\n}\n\npublic class MyEvent1Args : BaseEventArgs\n{ \xe2\x80\xa6 }\npublic class MyEvent2Args : BaseEventArgs\n{ \xe2\x80\xa6 }\n\n\npublic delegate void TestHandlerWithInheritance(BaseEventArgs baseEventArgs);\n\npublic event TestHandlerWithInheritance mTestHandler;\n\nmTestHandler += new TestHandlerWithInheritance(TestHandlerForEvent1Args);\nmTestHandler += new TestHandlerWithInheritance(TestHandlerForEvent2Args);\n\n    void TestHandlerForEvent1Args(BaseEventArgs baseEventArgs)\n    {\n        MyEvent1Args my_event1_args = (baseEventArgs as MyEvent1Args);\n        if (my_event1_args != null)\n        {\n            // Do stuff here\n            Sub1Enums mid = my_event1_args.MessageID;\n            byte[] data = my_event1_args.Data;\n        }\n    }\n\n    void TestHandlerForEvent2Args(BaseEventArgs baseEventArgs)\n    {\n        MyEvent2Args my_event2_args = (baseEventArgs as MyEvent2Args);\n        if (my_event2_args != null)\n        {\n            // Do stuff here\n            Sub2Enums mid = my_event2_args.MessageID;\n            byte[] data = my_event2_args.Data;\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

在解析算法中,我根据消息的内容有类似的内容:

\n\n
        if (mTestHandler!= null)\n        {\n            mTestHandler (new MyEvent1Args(Sub1Enums.ID1, new byte[] { 0x01 }));\n        }\n        if (mTestHandler!= null)\n        {\n            mTestHandler (new MyEvent2Args(Sub2Enums.ID2, new byte[] { 0x02 }));\n        }\n
Run Code Online (Sandbox Code Playgroud)\n