为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕田峪4524236 2021-12-05 16:50:22
我正在尝试在 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?
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

我认为你应该使用类似 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 = 20

PS:


如您所见,重载原始类型是个坏主意。它们在性质上与参考文献完全不同,参考文献很容易打乱你的整个逻辑。


查看完整回答
反对 回复 2021-12-05
  • 1 回答
  • 0 关注
  • 191 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信