ここで直面している重要な問題は、オブザーバブルのソースが必要だということです。.Interval
一般に、イベント、デリゲート、タスク、多くのオブザーバブル拡張 (や など.Generate
)、サブジェクトなど、さまざまなソースからオブザーバブルを作成できます。
あなたの場合、オブザーバブルの外部にあるコードを使用して、値をプッシュできるソースが必要です。この場合、サブジェクトはまったく問題ありませんが、デリゲートも使用できます。
サブジェクトを使用する場合、コードは問題ありません。唯一の欠点はupdateSubject.OnCompleted
、オブザーバブルを呼び出して終了できることです。
デリゲートを使用する場合、コードは次のようになります。
private Action<GameTime> updateGameTime = null;
public void Initialize()
{
component = new Component();
Observable
.FromEvent<GameTime>(a => updateGameTime += a, a => updateGameTime -= a)
.Subscribe((gameTime) => component.Update(gameTime));
}
public void Update(GameTime gameTime)
{
updateGameTime(gameTime);
}
このようにしてできることはupdateGameTime
、 new を渡すことだけですGameTime
。「誤って」シーケンスを終了することはできません。
現在、主語と対比を使用することに関する全体の問題Observable.Create
は、状態の 1 つです。コードでは状態が必要なので、サブジェクトは問題ありません。ただし、一般的には、可能な限り、状態をカプセル化することをお勧めします-それがあなたのObservable.Create
ために行います。
次の例を見てください。
var i = -1;
var query =
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
});
このオブザーバブルを 2 回サブスクライブすると、次の 2 つのシーケンスが得られます。
(1)
0
-4
16
-48
128
-320
768
-1792年
4096
-9216
(2)
0
-4096
16384
-49152
131072
-327680
786432
-1835008
4194304
-9437184
状態 (つまりvar i = -1;
) を使用したため、シーケンスが変わります。
コードを書いていたら、Observable.Create
この状態を避けることができました:
var query =
Observable
.Create<int>(o =>
{
var i = -1;
return
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
})
.Subscribe(o);
});
これは同じクエリですが、状態はカプセル化されているため、2 回サブスクライブすると次のようになります。
(1)
0
-4
16
-48
128
-320
768
-1792年
4096
-9216
(2)
0
-4
16
-48
128
-320
768
-1792年
4096
-9216
複雑なクエリを作成するときに、サブジェクトを使用するとはるかに簡単になると考える場合があり、一般に、それが間違いの原因です。この場合、主語を使用する前に、常に純粋な演算子のアプローチを見つけるようにしてください。できない場合は、サブジェクトの使用を にカプセル化しますObservable.Create
。
その外部状態が必要なため、サブジェクトを使用しても問題ない場合があります。