はじめに
UniRxを用いた開発を行っている時に、subject.AsObservable()
という形で目にすることが多いAsObservable()
メソッドの意味を調べてみました。
環境
Unity 2019 1.1f1
UniRx 6.2.2
結論
いくつかのインターフェースを実装しているsubject
をIObservable
にアップキャストして、IObservable
以外のインターフェースが持っている処理(OnNextなど)を禁止するためです。
実例
Subject<int> subject = new Subject<int>();
//IObservable<int>にアップキャスト
IObservable<int> stream = subject.AsObservable();
stream.Subscribe(l => Debug.Log(l));
stream.OnNext(1); //エラーになる
subject.OnNext(1); //エラーにならない
理由
まずSubject<T>
は
public sealed class Subject<T> : ISubject<T>, IDisposable, IOptimizedObservable<T> { ... }
のように、ISubject<T>
を実装しています。
そしてこのISubject<T>
は、
public interface ISubject<T> : ISubject<T, T>, IObserver<T>, IObservable<T> { ... }
のようにIObserver<T>
インターフェースとIObservable<T>
インターフェースを継承しています。
つまり、Subject<T>
クラスはIObserver<T>
インターフェースとIObservable<T>
インターフェースを実装しています。
また、AsObservable()
メソッドは、
public static IObservable<TSource> AsObservable<TSource>(
this IObservable<TSource> source
)
のようにIObservable
インターフェースの拡張メソッドとして定義されていて、subject
から流れてくる値をIObservable
型にキャストして返す役割を持ちます。
IObservable
型にキャストされると、IObservable
以外のインターフェースの持つメソッド(OnNext()
やOnError()
など)が使えなくなります。
まとめ
-
IObservable
インターフェースを実装しているSubject
型のインスタンスは、IObservable
の拡張メソッドであるAsObservable()
メソッドを使うことができる。 -
AsObservable()
メソッドはsubject
から流れてきた値をIObservable
型にキャストして返す処理を行う。 -
AsObservable()
メソッドを使うことによって、元々IObservable
以外のインターフェースのメソッドを使うこともできた(Subject
型のインスタンスである)subject
に、IObservable
以外のインターフェースのメソッドの使用を禁止させることができる。