Observable Not Null和Value Observable True

时间:2017-09-15 05:23:30

标签: c# reactivex

这有点难以解释,首先看一下代码:

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);
}

此代码似乎有效,但我不确定这是否是最好的方法。

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

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);
}

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

我正在使用&#34; UniRx&#34; Unity的图书馆。

1 个答案:

答案 0 :(得分:2)

更正了答案:啊,我现在看到你希望prop的空值发出false秒。在这种情况下,您可以简单地将空值映射到包裹的false,并将其展平为返回流:

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));
}

Obselete answer: 空值已经使用propWhere(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));
}