クラスclass C<T>
があるとします。オブジェクトがジェネリッククラスを継承するか、またはジェネリッククラスのメンバーであるかどうかをテストするにはどうすればよいですか?
私はa
がC
(又はC
自体である)から継承するクラスのメンバーである場合に真を返す関数f(_ a: Any) -> Bool
を書きたいです。私は専門化を気にしません:C<Int>
、C<Double>
、C<Whatever>
をすべて返すのはtrue
です。
それは、私はちょうどその関数の本体としてa is C
またはa as? C != nil
を書くことができるはずのように思える、しかし、これらの両方の遊び場にコンパイルされません。 swiftcは「C < _>」へのキャストで「ジェネリックパラメータ「T」」を推論できないと訴えています。インスタンスメソッドとしてC
の中にf
を書き込むと、C
は暗黙的にC<T>
であるため、let c = C<Int>(); c.f(C<Double>())
を書き込むとfalse
が返されます。
P
のC
が準拠しているプロトコルを作成して対処することができますが、それをテストしますが、それは良い解決策ではありません。それはちょうどハックです。
これを行う方法はありますか?それはちょうど、オブジェクトがのサブクラスであることを知っておくと便利ではないので、私は、あなたがこれを行うにするために言語機能が存在するとは思わない
class C<T> {
func test(_ a: Any) -> (Bool, Bool) {
return (type(of: a) == C.self, a is C)
}
}
class D: C<Double> { }
let d = D()
func f(_ a: Any) -> Bool {
return a is C // generic parameter 'T' could not be inferred in cast to 'C<_>'
}
d.test(C<Int>()) // false, false
// bad solution
protocol P { }
extension C: P { }
d is P // true
有用性についてご説明します。 'someObject'が特殊化されている型がわからないからといって、' C'から継承した知識が役に立たないということを意味するわけではありません。あるオブジェクト(例えば、ビュー階層内のスーパービュー)がタイプCであることを知っているだけで、その下のビューに関する一定の不変条件が成り立つことを意味するかもしれません。 –
@BenPiousビューの階層構造の場合は、 'tag'を使用してください。スーパービューのタグが何らかの値であるかどうかを調べることで、それがあなたが探しているビューかどうかを知ることができます。彼らは十分ではありませんか? – Sweeper
誰かが私がいくつかのビューのためにしたのと同じタグを選ぶことができました。さらに、 'C 'のユーザは、' C'から継承する型のインスタンスのタグを設定できないことを知る必要があります。あるいは、 'C'の実装の詳細を破ることになります。明らかにするために、 'C'のメンバーであることは、不変量が成り立つことを知るのに十分です。それは特定の例ではありません。だから私はそれをテストできるようにしたい。私が質問の最後に言ったように、 'C'(そして' C'のみ)に従う 'P'でジェネリックを消去しないと、私はそれをすることができないようです。 –