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

时间:2022-09-02 09:35:41

I am getting a compile error from the following property.
The error is:

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

"The modifier 'public' is not valid for this item"

“修饰符'public'对此项无效”

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

but if I remove the IWorkItemControl it compiles fine.

但如果我删除IWorkItemControl,它编译得很好。

Why am I getting this error and what is the difference of having / not having the interface name in the signature?

为什么我收到此错误,签名中是否有/没有接口名称有什么区别?

2 个解决方案

#1


Explicit interface implementation does not let you specify any access modifiers. When you implement an interface member explicitly (by specifying the interface name before the member name), you can access that member only using that interface. Basically, if you do:

显式接口实现不允许您指定任何访问修饰符。当您显式实现接口成员时(通过在成员名称之前指定接口名称),您只能使用该接口访问该成员。基本上,如果你这样做:

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

You can't do:

你做不到:

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

There are several use cases for EII. For example, you want to provide a Close method for your class to free up acquired resources but you still want to implement IDisposable. You could do:

EII有几个用例。例如,您希望为类提供Close方法以释放已获取的资源,但您仍希望实现IDisposable。你可以这样做:

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

This way, the consumers of class can only call Close directly (and they won't even see Dispose in Intellisense list) but you can still use the Test class wherever an IDisposable is expected (e.g. in a using statement).

这样,类的使用者只能直接调用Close(他们甚至不会在Intellisense列表中看到Dispose),但是你仍然可以在任何需要IDisposable的地方使用Test类(例如在using语句中)。

Another use case for EII is providing different implementations of an identically named interface member for two interfaces:

EII的另一个用例是为两个接口提供同名的接口成员的不同实现:

interface IOne {
   bool Property { get; }
}

interface ITwo {
   string Property { get; }
}

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

As you see, without EII it's not even possible to implement both interfaces of this example in a single class (as the properties differ just in return type). In other cases, you might want to intentionally provide different behavior for individual views of a class through different interfaces.

如您所见,没有EII,甚至不可能在单个类中实现此示例的两个接口(因为属性在返回类型上不同)。在其他情况下,您可能希望通过不同的接口有意为类的各个视图提供不同的行为。

#2


All elements of an interface must be public. After all, an interface is the public view of an object.

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

Since Properties is an element of an interface IWorkItemControl, it is already public, and you cannot specify its access level, even to redundantly specify that it is public.

由于Properties是IWorkItemControl接口的一个元素,因此它已经公开,您无法指定其访问级别,甚至可以冗余地指定它是公共的。

#1


Explicit interface implementation does not let you specify any access modifiers. When you implement an interface member explicitly (by specifying the interface name before the member name), you can access that member only using that interface. Basically, if you do:

显式接口实现不允许您指定任何访问修饰符。当您显式实现接口成员时(通过在成员名称之前指定接口名称),您只能使用该接口访问该成员。基本上,如果你这样做:

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

You can't do:

你做不到:

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

There are several use cases for EII. For example, you want to provide a Close method for your class to free up acquired resources but you still want to implement IDisposable. You could do:

EII有几个用例。例如,您希望为类提供Close方法以释放已获取的资源,但您仍希望实现IDisposable。你可以这样做:

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

This way, the consumers of class can only call Close directly (and they won't even see Dispose in Intellisense list) but you can still use the Test class wherever an IDisposable is expected (e.g. in a using statement).

这样,类的使用者只能直接调用Close(他们甚至不会在Intellisense列表中看到Dispose),但是你仍然可以在任何需要IDisposable的地方使用Test类(例如在using语句中)。

Another use case for EII is providing different implementations of an identically named interface member for two interfaces:

EII的另一个用例是为两个接口提供同名的接口成员的不同实现:

interface IOne {
   bool Property { get; }
}

interface ITwo {
   string Property { get; }
}

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

As you see, without EII it's not even possible to implement both interfaces of this example in a single class (as the properties differ just in return type). In other cases, you might want to intentionally provide different behavior for individual views of a class through different interfaces.

如您所见,没有EII,甚至不可能在单个类中实现此示例的两个接口(因为属性在返回类型上不同)。在其他情况下,您可能希望通过不同的接口有意为类的各个视图提供不同的行为。

#2


All elements of an interface must be public. After all, an interface is the public view of an object.

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

Since Properties is an element of an interface IWorkItemControl, it is already public, and you cannot specify its access level, even to redundantly specify that it is public.

由于Properties是IWorkItemControl接口的一个元素,因此它已经公开,您无法指定其访问级别,甚至可以冗余地指定它是公共的。