使用Rx,我有一个设置面板,用于控制是否启用操作以及应以什么速率运行。
这些属性存储在LibrarySettings类中,当通过前端滑块/复选框对属性进行更改时,可观察属性将根据更改进行选择。

我应该如何编写LibrarySettings类,以使它不会将setting.Value(整个LibrarySettings实例)设置为null。

IDisposable reader = setting.Value.Subscribe(options =>
{
    OperationOneEnabled = options.OperationOneEnabled;
    OperationTwoEnabled = options.OperationTwoEnabled;

    OperationOneRate = options.OperationOneRate;
    OperationTwoRate = options.OperationTwoRate;
});

IDisposable writer = this.WhenAnyPropertyChanged()
    .Subscribe(vm =>
    {
        settings.Write(new LibrarySettings(OperationOneEnabled, OperationOneRate,
            OperationTwoEnabled, OperationTwoRate));
    });

OperationOneRateProperty = this.WhenValueChanged(vm => vm.ScheduleRate)
    .DistinctUntilChanged()
    .Select(value => $"{value} seconds")
    .ForBinding();

 _CleanUp = new CompositeDisposable(reader, writer, OperationOneRateProperty);


因此,在LibrarySettings类中,我需要能够创建该属性

public IObservable<LibrarySettings> Value
{
    get { return _Value; }
    set { _Value = value; }
}


所以我尝试以下

Value = Observable.Create<LibrarySettings>(() =>
{
    new LibrarySettings(false, OperationOneEnable,OperationOneRate,
        OperationTwoEnabled, OperationTwoRate);
});


并得到一个


  delegate func<IObserver<LibrarySettings>> does not take 0 arguments

最佳答案

首先,这是无效的代码(不会编译)

Value = Observable.Create<LibrarySettings>(() =>
{
    new LibrarySettings(false, OperationOneEnable,OperationOneRate,
        OperationTwoEnabled, OperationTwoRate);
});


Observable.Create通常将Func<IObserver<T>, IDisposable>作为参数,因此应更正为

Value = Observable.Create<LibrarySettings>(observer =>
{
    observer.OnNext(new LibrarySettings(/*args*/));
    //What to do here?
    return Disposable.Empty; //Yuck.
});


可能更好,更简单的方法是只使用Observable.Return,但是这是可以观察到的。似乎它只是为了满足签名而使用Rx,因为这不符合Rx的精神。

相反,我想象您真正想要的是一个Settings属性,该属性在更改时会推送通知。为此,我认为有两种合理的方法


您具有LibrarySettings的只读属性,其中类型LibrarySettings是可变的和可观察的。
您具有LibrarySettings的可变属性和可观察属性,但是类型LibrarySettings是不可变的。


即是readonly属性

this.Setting.WhenAnyPropertyChanged()....

this.Setting.OperationOneRate = 25;
this.Setting.IsOperationOneEnabled= true;


类型是可变的

public class LibrarySettings : INotifyPropertyChanged
{
    public LibrarySettings()
    {
        IsOperationOneEnabled = false;;
        OperationOneRate = 0;
        IsOperationTwoEnabled = false;
        OperationTwoRate = 0;
    }
    public bool IsOperationOneEnabled { get;set; }
    public double OperationOneRate { get; set; }
    public bool IsOperationTwoEnabled { get;set; }
    public double OperationTwoRate { get; set;}

    #region INPC Impl
    #region
}


或不可变类型,然后对属性进行突变(每次都使用一个新实例)。您显然希望使用默认值创建它。

this.WhenValueChanges(t=>t.Setting)....

this.Setting = new LibrarySettings(OperationOneEnable, OperationOneRate,
    OperationTwoEnabled, OperationTwoRate);


像...

public class LibrarySettings
{
    public LibrarySettings(bool isOperationOneEnabled, double operationOneRate,
        bool isOperationTwoEnabled, double operationTwoRate)
    {
        IsOperationOneEnabled = isOperationOneEnabled;
        OperationOneRate = operationOneRate;
        IsOperationTwoEnabled = isOperationTwoEnabled;
        OperationTwoRate = operationTwoRate;
    }
    public bool IsOperationOneEnabled { get; }
    public double OperationOneRate { get; }
    public bool IsOperationTwoEnabled { get; }
    public double OperationTwoRate { get;}
}


我刚刚找到了您链接到的代码(您链接到存储库的根目录而不是实际的相关类)
* https://github.com/markiemarkus/Amadeus/blob/master/Amadeus/NovoApp/Models/LibrarySettings.cs


https://github.com/markiemarkus/Amadeus/blob/master/AmadeusNovoApp/Models/View/LibraryOptionsViewModel.cs


主要问题是这些行

Value = Observable.Create<LibrarySettings>(observer =>
{
    observer.OnNext(new LibrarySettings(false, OperationOneEnabled, OperationOneRate, OperationTwoEnabled, OperationTwoRate));
    return Disposable.Empty;
});


}

public IObservable<LibrarySettings> Value
{
     get { return _Value; }
     set { _Value = value; }
}

public void Write(LibrarySettings item)
{
     Value = Observable.Create<LibrarySettings>(observer =>
    {
        observer.OnNext(new LibrarySettings(false, OperationOneEnabled,
        OperationOneRate, OperationTwoEnabled, OperationTwoRate));
        return Disposable.Empty;
    });
}


您创建一个具有单个值的可观察序列(因此不是真正可观察的)。然后,您可以通过带有公共设置程序的属性来公开它(可设置的IObservable属性是什么意思!!)。最后,您在write方法中覆盖该实例,这意味着实际上已订阅属性原始值的任何人都将保留对孤立的Observable Sequence的订阅。

关于c# - 实现可观察的设置类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39327944/

10-16 08:53