我的解释,我有一些猜想:
有一个旧规则,如果您不想将接口成员实现为 public 类成员,那么您必须使用显式实现。这允许使指定的接口成员“难以访问”,因为在 您的 实现中它们不适合公共使用。请注意,即使这样,实现仍然是public。
这似乎也适用于现在可以声明自身且具有不公开可见性的接口部件,现在似乎是:any member of an interface that *isn't fully public* or that you *don't want to implement as public* must use explicit implementation。注意:我没有这方面的来源,我是从我所看到的情况中提炼出来的。
由于您的财产只是“半公开”,显然所有财产都属于该规则。
那么还有一条规则,引用documentation:
显式接口实现没有访问修饰符,因为它不能作为定义它的类型的成员来访问。相反,它只能在通过接口实例调用时才能访问。
这解释了为什么一旦使用显式实现(强制或非强制),就不能添加自己的访问修饰符,因为接口定义了适用的访问修饰符(如果省略,则默认为 public)。
这样做的后果
要访问公共 getter,所有客户端代码都需要使用IFoo:
-
var f = new Foo(); var x = ((IFoo)f).Bar; // 有效
-
IFoo f = new Foo(); var x = f.Bar; // 有效
-
var x = new Foo().Bar; // 不编译
由您决定是否值得将此要求强加给您的调用者。
如果需要,那么我看到了两种避免该要求的方法,第一种方法意味着将内部设置器排除在接口之外,仅将其放入Foo,但是使用设置器的代码必须使用Foo作为变量类型,它不能使用IFoo,而使用getter的代码可以为所欲为:
public interface IFoo
{
public string Bar { get; } // no setter (and you can omit `public`)
}
public class Foo : IFoo
{
public string Bar { get; internal set; } // add internal setter as class member
}
第二种方式,在接口中有一个internal void SetBar(string value),现在所有使用SetBar()的代码都必须使用IFoo作为变量类型,使用getter的代码可以为所欲为:
public interface IFoo
{
public string Bar { get; }
internal void SetBar(string value);
}
public class Foo : IFoo
{
public string Bar { get; private set; } // add private setter as class member
void IFoo.SetBar(string value) { Bar = value; } // use private setter
}