内部インターフェイスのメンバーを実装する方法
質問
現在、プロジェクトのコードベースをリファクタリングして、アセンブリの範囲を超えて役に立たないクラス/インターフェイスを(パブリックではなく)内部として宣言するようにしました。しかし、次のコードで問題が発生しました:
internal interface IFirstInterface
{
...
}
internal interface ISecondInterface
{
IFirstInterface First{ get; }
...
}
public class Implementer : ISecondInterface
{
public IFirstInterface First {get; private set;}
...
}
私の質問:
-
内部インターフェイスのメンバーを公開する必要があるのはなぜですか?内部クラスにインターフェースを実装する場合、実装されるメンバーは内部にすべきではありませんか?これは、クラスが内部であるため、インターフェイスメンバがパブリックにアクセスできないため、大きな問題ではありません。直感に反しているようです。
-
主な問題は上記のシナリオにあります。これはIFirstInterfaceのパブリックゲッターが内部インターフェイスであるため、つまりコンパイラから次のエラーが発生するためです。
一貫性のないアクセシビリティ:プロパティ タイプ「IFirstInterface」は少ない プロパティよりアクセス可能 'Implementer.First'
これを回避する方法はありますか?
注:このリファクタリングの練習にはおそらくほとんど価値がないことに気付きますが、内部修飾子の意味をより深く理解するのに良い方法だと思いました。
解決
注意点- Implementer
は内部クラスであるため、実際に提供したコードはコンパイルします 。問題は、 Implementer
がパブリックの場合に発生します。
これを巡る方法は、明示的なインターフェース実装を使用することです:
public class Implementer : ISecondInferface
{
private IFirstInterface first;
IFirstInterface ISecondInterface.First { get { return first; } }
}
セッターを定義することのできないインターフェースを明示的に実装しているため、そこにセッターを含めることはできません。代替手段としてこれを行うことができます :
public class Implementer : ISecondInterface
{
internal IFirstInterface First { get; private set; }
IFirstInterface ISecondInterface.First { get { return First; } }
}
内部インターフェイスにパブリックメンバーがあるのは残念です。このようなことは複雑です。パブリックインターフェイスに内部メンバー(実装者または宣言者の内部に何があるのでしょうか?)があるのは奇妙ですが、内部インターフェイスの場合はもっと意味があります。
他のヒント
内部インターフェースのメンバーを公開する必要があるのはなぜですか?
インターフェイスを定義するとき、すべてのインターフェイスメンバーは public
であるため、メンバーのアクセスレベルは定義しません。インターフェース自体が internal
であっても、メンバーは public
と見なされます。そのようなメンバーの暗黙的な実装を行う場合、署名は一致する必要があるため、 public
である必要があります。
ゲッターの公開については、代わりにインターフェイスの explicit 実装を作成し、 internal
プロパティを作成して値を公開することをお勧めします。
internal IFirstInterface First { get; private set; }
IFirstInterface ISecondInterface.First
{
get { return this.First; }
}
この投稿は数年前のものですが、パブリッククラスに内部インターフェイスを実装できることは注目に値します。次のリンクをご覧ください:
http://forums.create.msdn.com/forums/p/29808/ 167820.aspx
http://msdn.microsoft.com/en-us/ library / aa664591%28VS.71%29.aspx
最初のリンクの例:
internal interface ISecretInterface
{
string Property1 { get; }
}
public class PublicClass : ISecretInterface
{
// class property
public string Property1
{
get { return "Foo"; }
}
// interface property
string ISecretInterface.Property1
{
get { return "Secret"; }
}
}