Observable Not Null 和 Value Observable True

Observable Not Null and Value Observable True

这个解释起来有点难,先看代码:

public static IObservable<bool> NotNullAnd<T>(IReadOnlyReactiveProperty<T> prop,
    Func<T, IObservable<bool>> andSelector)
{
    var notNull = prop.Select(l => l != null);

    var isExecuting = prop
        .Where(l => l != null)
        .SelectMany(l => andSelector(l));

    return notNull.CombineLatest(isExecuting, (x, y) => x && y);
}

此代码似乎有效,但我不确定这是否是执行此操作的最佳方法。

基本上,我正在寻找一种方法来检查对象上的可观察对象何时触发,但该对象可能为空,因此我需要先检查一下。因此,组合是检查 属性 何时更改,如果不为空,则在对象上侦听另一个 属性 ...很难解释,但也许测试可能有助于解释:

private class Loader
{
    public ReactiveProperty<bool> IsExecuting
        = new ReactiveProperty<bool>();
}

[Test]
public void TestNotNullAnd()
{
    var loaderProp = new ReactiveProperty<Loader>();

    var isExecutingProp = NotNullAnd(loaderProp, l => l.IsExecuting)
        .ToReadOnlyReactiveProperty();

    var loader = new Loader();

    Assert.IsFalse(isExecutingProp.Value);

    loaderProp.Value = loader;
    Assert.IsFalse(isExecutingProp.Value);

    loaderProp.Value.IsExecuting.Value = true;
    Assert.IsTrue(isExecutingProp.Value);

    loaderProp.Value.IsExecuting.Value = false;
    Assert.IsFalse(isExecutingProp.Value);

    loaderProp.Value.IsExecuting.Value = true;
    Assert.IsTrue(isExecutingProp.Value);

    loaderProp.Value.IsExecuting.Value = false;
    Assert.IsFalse(isExecutingProp.Value);

    loaderProp.Value.IsExecuting.Value = true;
    Assert.IsTrue(isExecutingProp.Value);

    loaderProp.Value = null;
    Assert.IsFalse(isExecutingProp.Value);

    loaderProp.Value = loader;
    Assert.IsTrue(isExecutingProp.Value);
}

如前所述,所有这些测试都通过了,但我不确定是否有更好的方法,而且我担心我在这里某处引入了内存泄漏,因为我没有处理监听 "l.IsExecuting"

我正在为 Unity 使用 "UniRx" 库。

正确答案: 啊,我现在明白了,您希望 prop 中的空值发出 falses。在这种情况下,您可以简单地将空值映射到包装的 false ,然后将其展平到 return 流中:

public static IObservable<bool> NotNullAnd<T>(IReadOnlyReactiveProperty<T> prop,
    Func<T, IObservable<bool>> andSelector)
{
  return prop.SelectMany(l => l == null ? Observable.Return(false) : andSelector(l));
}

过时的答案: prop 的值已经用 Where(l => l != null) 过滤掉空值,因此构造 notNull 并将其组合成 isExecuting 是多余的。此外,这很危险,因为 notNullisExecuting 可能不会完全同步,并且您可能会意外地翻转某些值,尤其是当您链接更多运算符时。

以下应该足够了:

public static IObservable<bool> NotNullAnd<T>(IReadOnlyReactiveProperty<T> prop,
    Func<T, IObservable<bool>> andSelector)
{
    return prop
        .Where(l => l != null)
        .SelectMany(l => andSelector(l));
}