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

Posted

技术标签:

【中文标题】C#中接口成员的访问修饰符【英文标题】:Access modifiers on interface members in C# 【发布时间】:2010-11-07 20:21:09 【问题描述】:

我收到以下属性的编译错误。 错误是:

“修饰符‘public’对此项无效”

public System.Collections.Specialized.StringDictionary IWorkItemControl.Properties

    get  return properties; 
    set  properties = value; 

但如果我删除 IWorkItemControl 它编译正常。

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

【问题讨论】:

【参考方案1】:

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,甚至不可能在单个类中实现本示例的两个接口(因为属性仅在返回类型上有所不同)。在其他情况下,您可能希望通过不同的接口为类的各个视图提供不同的行为。

【讨论】:

【参考方案2】:

接口的所有元素都必须是公共的。 毕竟,接口对象的公共视图。

由于 Properties 是接口 IWorkItemControl 的一个元素,它已经是公共的,您不能指定它的访问级别,即使是多余地指定它是公共的。

【讨论】:

这不是一个强有力的理由,因为您仍然必须为所有隐式实现的成员手动指定 public。如果是这种情况,编译器也可以自动假定它们是公开的。

以上是关于C#中接口成员的访问修饰符的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中,我们可以对接口使用受保护的访问修饰符吗?

在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?

为啥接口成员没有访问修饰符? [复制]

C#关键字:访问修饰符

C#中的默认访问修饰符

C#中4个访问修饰符(随笔)