C#中接口成员的访问修饰符

16

以下属性导致了编译错误。
错误信息是:

"修饰符 'public' 对此项无效"

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

但是如果我去掉 IWorkItemControl,它就可以编译通过了。

为什么会出现这个错误?在签名中有/没有接口名称有什么区别?

2个回答

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方法(甚至不会在Intellisense列表中看到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
这不是一个非常充分的理由,因为您仍然需要手动指定所有隐式实现成员的公共访问修饰符。如果是这样的话,编译器也可以自动将它们假定为公共的。 - Mehrdad Afshari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接