2011-08-30 26 views
18

私はインターフェイスを継承するクラスを持っています。インターフェイスメンバメソッドは、アクセス修飾子なしで私のクラスで実装されています(デフォルトではprivateです)。クラスで実装されているC#インターフェイスメソッドを公開する必要があるのはなぜですか?

「公開されていないため、インターフェイスメンバーを実装できません」というエラーが表示されます。

なぜ許可されていませんか?アクセシビリティを上書きすることはできませんか?

答えて

29

理由の例だそれは視界を上書きできるようにするには意味がありません:あなたの労働者がタイプBである場合に発生

interface someI 
{ 
    void doYourWork(); 
} 
public class A : someI 
{ 
    public void doYourWork() 
    { 
     //... 
    } 
} 

public class B : someI 
{ 
    private void doYourWork() 
    { 
     //... 
    } 
} 
void Main() 
{ 
    List<someI> workers = getWorkers(); 
    foreach(var worker in workers) 
     worker.doYourWork(); 
} 

何?メソッドを公開しているかのように呼び出していますが、それはプライベートメソッドです。この機能が必要な場合は、実際にプライベートな方法ではありませんか?

あなただけのインターフェイスを介して参照されたとき、それは公衆になりたい場合は、あなたがそのように定義することができます。

public class B : someI 
{ 
    void someI.doYourWork() 
    { 
     //... 
    } 
} 

そして、あなたはこれで終わる:そのような他の言語で

var b = new B(); 
b.doYourWork(); // Not accessible 
((someI)b).doYourWork(); // Accessible 
+3

私は、開封されていないクラスでは、実装が保護された仮想メンバを使用して同じ名前と署名を持つパブリッククラスメンバを公開しないインターフェイスを実装する必要があります。残念なことに、最も近いものはC#でそれを行うことに来ることができるのは、インターフェイス実装が単に保護された仮想メソッドを呼び出すことです。それ以外の場合、派生クラスがインタフェースを再実装する場合、親実装を呼び出す方法はありません。 – supercat

+1

@supercat多分早いですが、私があなたに従っているかどうかはわかりません。それ以外の場合、派生クラスがインターフェースを再実装すると、親実装を呼び出す方法はありません。なぜあなたは、インターフェイスを実装している保護されたメソッドを持っていたいのですか?(この場合、インターフェイスを通してアクセスすることはできません;実装しているインターフェイスが分からない派生クラスでのみです) – Rob

+2

In vb.net 'Protected Overridable Sub DoSomethingImpl()はIDoSomething.DoSomething'を実装します;外部コードはインタフェースを介してそのメソッドを呼び出すことしかできませんが、派生クラスはメソッドをオーバーライドでき、オーバーライド内で親メソッドを呼び出すことができます。 C#では、同様に保護されたメソッドを使用してインターフェイスを実装することができれば便利ですが、スペックを担当する人はそのオプションを許可しません。もっとも近いものは、保護されたメソッド 'DoSomethingImpl()'を呼び出すメソッドで明示的にインタフェースを実装することです。注意してください... – supercat

20

メソッドはpublicで実装する必要があります。これらのメソッドは、インターフェイス経由で呼び出し可能でなければならず、したがってインターフェイスがタイプとしてアクセスできる場所から実装する必要があります。

変更」には、そのメソッドの可視性がいくつかあります。所与:

public interface IFoo 
{ 
    bool IsFoo(); 
} 

A.メソッドexplicitly

public class Foo : IFoo 
{ 
    bool IFoo.IsFoo() { return true; } 
} 

を実装方法は、インターフェースを介して利用できるようになり

B.変更の視認性(この場合IFoo。)インターフェイス

インターフェイスをinternalの代わりに定義します。 public。しかし、結果としてFoointernalでなければなりません。

+0

vb.netのように、インタフェースを実装するメソッドには特別なアクセシビリティは必要ありません。 C#では、暗黙のインターフェイス実装がパブリックである必要があります。これは、指定されたクラスメンバもインターフェイス実装と見なす必要があることを示すためのキーワードまたは表記がないためです。 – supercat

5

インタフェースの実装をパブリックにすることは、単に論理的な要件です。インターフェイスを実装すると、コンパイラに "やあ、私はこのインターフェイス上のすべてのメソッドを実装している"と伝えています。したがって、このメソッドをプライベートにすると、アクセスできない状態になり、論理的には実装されません。インターフェイスは、自分のオブジェクトを使用するコードへのコントラクトとして機能し、オブジェクトのインターフェイスに定義されたメソッドをいつでも呼び出すことができると言います。実装方法がプライベートであった場合、これ以上は当てはまりません。

インプリメンテーションを非表示にしたい場合は、Intellisenseのように、@ Bryanのように明示的にメソッドを実装するだけです。ここで

+0

"インターフェイスは、オブジェクトのインターフェイスに定義されているメソッドをいつでも呼び出せるという、オブジェクトを使用するコードへのコントラクトとして機能します。それは厳密には当てはまりません。つまり、クラスのインスタンスをインタフェースにキャストし、インタフェース参照を介してインタフェースメソッドを_then_呼び出すことができます。これは契約であり、インターフェイスに最初にキャストせずにインターフェイスのメソッドを呼び出すことはできません。もちろん、キャストも必要とせずにインターフェイスメソッドを公開する必要がありますが、これは技術的要件でもなく、常に論理的要件でもありません。 – Darryl

関連する問題