TL;DR
元のプロパティの派生型を返すように宣言を変更できるように、インターフェイスでプロパティを非表示にすることの何が問題になっていますか?
これは以前に尋ねられたにちがいないと確信していますが、見つけることができず、長い質問をお詫びします。
この状況があるとします:
public interface A
{
B TheB{get;}
}
public interface MoreSpecificA : A
{
MoreSpecificB TheMoreSpecificB{get;}
}
public interface B{...}
public interface MoreSpecificB:B{...}
MoreSpecificA
のユーザーが である B にアクセスできるようにしたいと思いますMoreSpecificB
。呼び出しTheB
てキャストするか、メソッドを呼び出すことでこれを行うことができますTheMoreSpecificB
。MoreSpecificA
次のように宣言することもできます。
public interface MoreSpecificA : A
{
new MoreSpecificB TheB{get;}
}
これで、同じメソッドを使用してMoreSpecificB
.
を使用しnew
てメソッドを非表示にすると歯が立たなくなりますが、なぜこれが悪い考えなのですか? ここで行うのは合理的なことのようです。
これについて私が見たほとんどの場合の一般的な提案は、代わりにジェネリックを使用することのようですが、これには問題があるようですMoreSpecificA
。インスタンスにアクセスするときにあいまいさを与える拡張を行うには、A
必要MoreSpecificA
かどうかがわからないためですA
TheB
MoreSpecificA
A.TheB
MoreSpecificA.TheB
public interface ABase<T> where T : B
{
T TheB{get;}
}
public interface A : ABase<B>
{
}
public interface MoreSpecificA : ABase<MoreSpecificB>,A
{
}
public class blah
{
public A GetA(MoreSpecificA specificA)
{
return specificA; //can't do this unless MoreSpecificA extends A
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here, if MoreSpcificA extends A
}
}
これは、MoreSpecificA で新しい TheB を宣言することで解決できます (ただし、再び新しい問題が発生します)。
MoreSpecificA が A を拡張しない場合、blah
上記のクラスの最初のメソッドは、MoreSpcificA を A に変換できないため、エラーになります。
これを書いているときに、 BaseA を次のように反変であると宣言すると、次のようになることに気付きました。
public interface ABase<out T> where T : B
{
T TheB{get;}
}
そして私のクラスは
public class blah
{
public ABase<B> GetA(MoreSpecificA specificA)
{
return specificA;
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here
}
}
それから私は両方の長所を得る. このソリューションの適用可能性は、A
に何かを追加するかどうかによって異なりますABase
か?
それとも、元のメソッドの派生型を返すために派生型のメソッドを非表示にするという当初の計画は大丈夫ですか?