2009-07-03 11 views
16

次のプロパティからコンパイルエラーが発生します。 「修飾子 『公共』はこの項目のために有効ではありません」C#のインターフェイスメンバのアクセス修飾子

public System.Collections.Specialized.StringDictionary IWorkItemControl.Properties 
{ 
    get { return properties; } 
    set { properties = value; } 
} 

が、私はIWorkItemControlを削除する場合には罰金コンパイル:
エラーです。

なぜこのエラーが発生するのですか、シグネチャにインターフェイス名を持つ/持っていないという違いは何ですか?

答えて

41

Explicit interface implementationは、アクセス修飾子を指定することはできません。明示的に(メンバー名の前にインターフェイス名を指定して)インターフェイスメンバを実装すると、そのメンバにはそのインターフェイスのみを使用してアクセスできます。基本的に、あなたが行う場合:

System.Collections.Specialized.StringDictionary IWorkItemControl.Properties 
{ 
    get { return properties; } 
    set { properties = value; } 
} 

あなたは行うことはできません。

MyClass x = new MyClass(); 
var test = x.Properties; // fails to compile 
// You should do: 
var test = ((IWorkItemControl)x).Properties; // accessible through the interface 

はEIIのためのいくつかのユースケースがあります。たとえば、クラスにCloseメソッドを提供して、取得したリソースを解放したいが、依然としてIDisposableを実装したいとします。あなたは何ができる:

class Test : IDisposable { 
    public void Close() { 
     // Frees up resources 
    } 
    void IDisposable.Dispose() { 
     Close(); 
    } 
} 

この方法で(、クラスの消費者が直接的にのみCloseを呼び出すことができます(と彼らもインテリセンスリストにDisposeは表示されません)が、あなたはまだIDisposableが期待されている場所Testクラスを使用することができます例えば、usingステートメント)。ご覧のとおりEIIせず、それはこの例の両方のインターフェイスを実装するためにことも可能ではありません、

interface IOne { 
    bool Property { get; } 
} 

interface ITwo { 
    string Property { get; } 
} 

class Test : IOne, ITwo { 
    bool IOne.Property { ... } 
    string ITwo.Property { ... } 
} 

:EIIのため

別のユースケースは、二つのインタフェースのために同じ名前のインターフェイスメンバの異なる実装を提供しています単一のクラス(戻り値の型だけでプロパティが異なるため)他のケースでは、意図的に、異なるインターフェースを介してクラスの個々のビューに対して異なる動作を提供することができます。

0

インターフェイスのすべての要素は公開されている必要があります。結局のところ、というインタフェースは、オブジェクトの公開ビューであるです。

プロパティインターフェイスの要素IWorkItemControlあるので、それはすでに公開されて、そしてあなたも重複し、それが公共であることを指定するには、そのアクセスレベルを指定することはできません。

+1

これは、暗黙的に実装されたすべてのメンバーに対してpublicを手動で指定する必要があるため、あまり理由はありません。それが当てはまる場合、コンパイラはそれらを自動的に公にすることもできます。 –

+0

これは間違っています。なぜなら、内部インターフェイスを持つことができるからです。 –