C# 对象与类通信

C# 对象与类通信,c#,C#,我一直在寻找不同的方法来实现对象和类之间的通信,以保持一种解耦、封装、面向对象的方法。我所发现的往往集中在一个特定的实现上,我从来没有看到过比较,也没有看到这些方法的相对优缺点。我也确信我并没有意识到所有这些。此外,我的特定应用程序严重依赖于用户输入(游戏开发),这又增加了另一个因素 对我来说,最基本也是最不吸引人的方法是静态类和变量,其中每个对象和类访问一个集中的变量列表。在我看来,这显然会非常迅速地变得非常拥挤,并且对于除小型应用程序之外的任何其他应用程序来说都是非常不实用的。我还研究了MV

我一直在寻找不同的方法来实现对象和类之间的通信,以保持一种解耦、封装、面向对象的方法。我所发现的往往集中在一个特定的实现上,我从来没有看到过比较,也没有看到这些方法的相对优缺点。我也确信我并没有意识到所有这些。此外,我的特定应用程序严重依赖于用户输入(游戏开发),这又增加了另一个因素

对我来说,最基本也是最不吸引人的方法是静态类和变量,其中每个对象和类访问一个集中的变量列表。在我看来,这显然会非常迅速地变得非常拥挤,并且对于除小型应用程序之外的任何其他应用程序来说都是非常不实用的。我还研究了MVC和MVVC(足够学习基本知识了),但从我所看到的情况来看,它们不适用于游戏循环所需的恒定输入和机制。最后,我当前选择的方法是一个事件系统,其中静态类包含将委托添加到特定事件的函数,当调用该事件时,将执行所有这些函数。我当前的实现基本上是这样的:

public static class EventManager {

    private static Dictionary<EVNT, Delegate> eventTable = new Dictionary<EVNT, Delegate>();

    public static void AddHandler(EVNT evnt, Action action)
    {
        if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
        else eventTable[evnt] = (Action)eventTable[evnt] + action;
    }

    public static void AddHandler<T>(EVNT evnt, Action<T> action)
    {
        if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
        else eventTable[evnt] = (Action<T>)eventTable[evnt] + action;
    }
    //More multi-variable overloads...

    public static void Broadcast(EVNT evnt)
    {
        Delegate d;
        if (eventTable.TryGetValue(evnt, out d))
        {
            Action action = d as Action;
            if (action != null) action();
        }
    }

    public static void Broadcast<T>(EVNT evnt, T param)
    {
        Delegate d;
        if (eventTable.TryGetValue(evnt, out d))
        {
            Action<T> action = d as Action<T>;
            if (action != null) action(param);
        }
    }

    public static void RemoveHandler(EVNT evnt, Action action)
    {
        if(eventTable[evnt] != null)
            eventTable[evnt] = (Action)eventTable[evnt] - action;
        if (eventTable[evnt] == null)
            eventTable.Remove(evnt);
    }

    public static void RemoveHandler<T>(EVNT evnt, Action<T> action)
    {
        if (eventTable[evnt] != null)
            eventTable[evnt] = (Action<T>)eventTable[evnt] - action;
        if (eventTable[evnt] == null)
            eventTable.Remove(evnt);
    }
}
公共静态类事件管理器{
私有静态字典eventTable=新字典();
公共静态void AddHandler(EVNT EVNT,Action Action)
{
如果(!eventTable.ContainsKey(evnt))eventTable[evnt]=操作;
else eventTable[evnt]=(操作)eventTable[evnt]+操作;
}
公共静态void AddHandler(EVNT EVNT,Action Action)
{
如果(!eventTable.ContainsKey(evnt))eventTable[evnt]=操作;
else eventTable[evnt]=(操作)eventTable[evnt]+操作;
}
//更多多变量重载。。。
公共静态无效广播(EVNT EVNT)
{
d代表;
if(eventTable.TryGetValue(evnt,输出d))
{
动作动作=d为动作;
如果(action!=null)action();
}
}
公共静态无效广播(EVNT EVNT,T参数)
{
d代表;
if(eventTable.TryGetValue(evnt,输出d))
{
动作动作=d为动作;
if(action!=null)action(param);
}
}
publicstaticvoidremoveholder(EVNT-EVNT,Action-Action)
{
if(eventTable[evnt]!=null)
eventTable[evnt]=(操作)eventTable[evnt]-操作;
if(eventTable[evnt]==null)
eventTable.Remove(evnt);
}
publicstaticvoidremoveholder(EVNT-EVNT,Action-Action)
{
if(eventTable[evnt]!=null)
eventTable[evnt]=(操作)eventTable[evnt]-操作;
if(eventTable[evnt]==null)
eventTable.Remove(evnt);
}
}

是否有不同或更好的方法来实现对象和类的“解耦”?我还可以通过什么方式实现通信,无论通信是否低劣,以及如何最好地遵循面向对象的实践来实现通信?

使用内置的IObserver和IObservable接口,实现观察者模式,让您的可观察推送通知到订阅的观察者,您可能会从中受益。看看这个例子:


您可能还想看看本文中链接到的被动扩展库,但它们涉及的内容更多。

您看过MassTransit吗?你是想只停留在进程中吗?是的,不幸的是,外部连接不是我大部分开发工作的一个选项,但这看起来确实是一个值得探索的有趣的解决方案。感谢链接,这是一本很好的读物。我不是很肯定,但我的印象是事件系统基本上是观察者模式或中介者模式的实现。将通知放入广播类有什么特殊的好处吗?@cjmarsh我认为这取决于代理在管理器中注册的方法的范围。如果您注册了显著改变全局状态的方法,而很少有人会这样做,那么您可能会遇到问题。您可以使用观察者模式来限制这一点,方法是不直接从观察者访问状态,只访问被观察者传递给观察者方法的状态。另一种看待它的方式是Broadcast()的概念——在您的静态类中,它更像“Run()”。此事件管理器不是真正的广播,这是一个void方法的跑步者。它不知道在其中注册了事件的对象的任何信息。只要您的整个设计模式是“事务脚本”,这就可以工作,但如果您需要跨方法调用协调状态,就会遇到问题。(症状:必须按特定顺序调用方法)