2017-02-04 10 views
0

私はクラス内にIObservable<Item>を持っており、与えられた時刻に最後のアイテムを観測可能にプッシュする読み取り専用プロパティを公開したいと思います。したがって、Itemの単一の値を提供します。最後にObservable(Sequence)にプッシュされたアイテムを取る

値がプッシュされていない場合は、デフォルトのの値を戻す必要があります。

私は観察可能なものを購読したり、 "バッキングフィールド"を持たなくてもこれを行うことができますか?

+0

何あなたは「最後に観察可能なものに押し込まれたアイテム」を意味しますか?観測可能な現在の値? –

+0

はい!観測可能なシーケンスが{1,4,6、... 400}の場合、プロパティの読み取りは400 – SuperJMN

答えて

2

観察できるが、それは、より論理的な概念ですが、物理的な「もの」ではありません。 RxはしばしばLINQと比較され、それはかなりの時間の公正な比較です。 LINQの列挙型は、学習目的でListに似ています。

しかし、Rx側では、Listと同等のものはありません。観測可能なのは一時的なデータ構造であり、すべての演算子はこの過渡状態を処理します。あなたが永続的な状態を探しているなら、あなたはRxを離れることになります。

このように言えば、ある種の状態に観察可能なものを変換することはよくある問題です。あなたに役立つパッケージがいくつかあります:ReactiveUIがおそらく最もよく知られています。 ReactivePropertyは別のものです。これらのパッケージには欠陥がありますが、あなたに役立つかもしれません。

あなたは、単にバッキングフィールドを取得する簡単な方法を探しているなら、バッキングフィールドをボイラーは、めっきなしで、これは動作します:

public static class ReactivePropertyExtensions 
{ 
    public static ReactiveProperty<T> ToReactiveProperty<T>(this IObservable<T> source) 
    { 
     return new ReactiveProperty<T>(source); 
    } 

    public static ReactiveProperty<T> ToReactiveProperty<T>(this IObservable<T> source, T defaultValue) 
    { 
     return new ReactiveProperty<T>(source, defaultValue); 
    } 
} 

public class ReactiveProperty<T> : IDisposable 
{ 
    private IObservable<T> Source { get; } 
    private IDisposable Subscription { get; } 
    public T Value { get; private set; } 

    public ReactiveProperty(IObservable<T> source) 
     : this(source, default(T)) { } 

    public ReactiveProperty(IObservable<T> source, T defaultValue) 
    { 
     Value = defaultValue; 
     Source = source; 
     Subscription = source.Subscribe(t => Value = t); 
    } 

    public void Dispose() 
    { 
     Subscription.Dispose(); 
    } 
} 

使用例:

var ticker = Observable.Interval(TimeSpan.FromSeconds(1)) 
    .Publish().RefCount(); 

var latestTickerValue = ticker.ToReactiveProperty(); 
Console.WriteLine(latestTickerValue.Value); 
await Task.Delay(TimeSpan.FromSeconds(1)); 
Console.WriteLine(latestTickerValue.Value); 
await Task.Delay(TimeSpan.FromSeconds(3)); 
Console.WriteLine(latestTickerValue.Value); 
+0

しばらくして、私はあなたの答えを読んでいます。 ReactUIとReactiveProperty =>「これらのパッケージには欠陥がありますが、あなたを助けてくれるかもしれません」と理解していないという声明があります。どういう意味ですか?なぜ彼らは欠陥があると思いますか?前もって感謝します! – SuperJMN

+0

これはすべての意見ですので、これが正しいフォーラムかどうかはわかりません:ReactivePropertyは、1つのパッケージ内のすべてのプラットフォームをサポートするため、膨大な数の依存関係があります。だから1つの関数やクラスだけが必要な場合は、プロジェクトに大きな膨らみをもたらします。 – Shlomo

+1

ReactiveUIは、時々刻々と変化する不連続な状態で、不十分な書類が不足しているようです。 Reactive Propertiesに必要な定型文もまた厄介です。あなたが私に尋ねたなら、それは本当に残念です。それはとてもすごく近いですが、いつも2つのステップのようです。 – Shlomo

2

熱いと見なします。

observable = source.Replay(1); observable.Connect();

のために価値を提供します

public int Value => observable.Take(1).Amb(Observable.Return(defaultValue)).Wait();

これは何の値がプッシュされていない場合のデフォルト値を返します。

リアクティブから状態への移行が必要なので、バッキングフィールドはひどいオプションではありません。あなたは購読したくないと言いましたが、何かを観察することを言いました:何か、どこかで購読する必要があります。ただ、少しここでアスティの答え@補うために、そしておそらくあなたの欲求不満のお手伝いを

+0

OKを返しますが、それは非同期です。私のプロパティは非同期であってはなりません。また、LastAsyncは、シーケンスが終了したときに最後の要素を返しますが、最後にプッシュされた最後の値を返す必要はありません。 – SuperJMN

+0

@ SuperJMNオブザーバブルがバッキングフィールドなしで実行されている間に、最後の値をオブザーバブルにプッシュしますか?それは観察可能な完了とは何の関係もありません。 – Asti

+0

はい、そうです! – SuperJMN

関連する問題