猿问

用于观察者模式的 C# Float Wrapper

我正在尝试在 C# 中实现可观察的本机数据类型(浮点数、整数、字符串、列表)。我应该补充一点,我对 C# 相当陌生,并且来自 C++ 背景。


我的第一个想法是有一个像这样的可观察界面:


public interface IObservable {


    void registerObserver(IObserver observer);


    void deregisterObserver(IObserver observer);


    void notifyObservers();

}

然后为重载运算符的本机数据类型(例如浮点数)创建包装器,以便(大部分)无缝使用:


Float f1 = new Float(0);

Float f2 = f1 + 2;

这必须是一个抽象基类,因为接口不能重载运算符。


然后我想创建一个 ObservableFloat,它结合了两个想法,但在其状态发生任何变化时调用 notifyObservers。使用它的类会将它视为 Float,并且不知道它在内部也是一个 Observable。


为此,我通常会重载赋值运算符,而不是执行以下操作:


return new Float(f1.value + f2.value);

它会修改第一个实例并返回它。但是由于赋值似乎总是会改变引用,所以我会在第一次赋值操作中丢失我的 observable 和它的观察者列表,对吗?


我发现这篇文章使用 C# 中的事件实现了一个观察者:链接 这段代码:


private State _state;


public State MyState

{

    get { return _state; }

    set

    {

        if (_state != value)

        {

            _state = value;

            Notify();

        }

    }

}

基本上是我想要的:当 State 变量被分配一个新值时,它会进行分配并调用一个函数。有什么方法可以在屏蔽 using 类(示例中的 Product)的同时实现这一点,使其不知道该变量是一个 Observable?


慕田峪4524236
浏览 192回答 1
1回答

MMMHUHU

我认为你应该使用类似 fluent 的东西来获得灵活性,而不是重载原始类型及其运算符,只是为了将它们注入到它不属于的地方:public interface INumeric{    INumeric Add(INumeric num);    INumeric Sub(INumeric num);    INumeric Mul(INumeric num);    INumeric Div(INumeric num);   }因此,例如,如果您想复制原始类型的行为,您将在里面得到类似的东西:public INumeric Sub(INumeric b){    var a = this;    return new Numeric(a.Value-b.Value);//obviuously, no notify here}如果您想以流畅的方式使用实例并通知观察者:public INumeric Sub(INumeric b){    var a = this;    a.Value = a.Value - b.Value;//notify 'a' observers or whatever here.    return a;}在代码它看起来像这一点,并在分配不会断裂,但小动作的提防与引用(工作时下面可以迷惑你OMG这将是不可能的调试):var a = new Numeric(10);var b = new Numeric(2);a = a.Sub(b)//10 - 2 = 8     .Add(a)//8 + 8 = 16     .Add(b);//16 + 2 = 18并以原始形式:a = a - b + a + b; //10 - 2 + 10 + 2 = 20PS:如您所见,重载原始类型是个坏主意。它们在性质上与参考文献完全不同,参考文献很容易打乱你的整个逻辑。
随时随地看视频慕课网APP
我要回答