Abe*_*bel 54 c# inheritance interface explicit-interface
我倾向于支持显式接口实现而非隐式接口实现,因为我认为针对接口而不是针对实现进行编程通常是可取的,而且在处理Web服务时通常是必需的.
也就是说,我想知道为什么以下是非法的显式接口声明和合法的隐式接口:
interface IConnection
{
string ConnectionString { get; }
}
class Connection1 : IConnection
{
// private set is illegal, won't compile
string IConnection.ConnectionString { get; private set; }
}
class Connection2 : IConnection
{
// private set is legal now, it is not part of the interface
string ConnectionString { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我知道如何解决这个问题,因为同时拥有一个显式和隐式接口是合法的,而且我可以使隐式接口实现完全私有.
然而,我想知道这背后的原因.因为从技术上讲,内部编译的私有方法set_IConnection_ConnectionString
不需要是接口的一部分,对吧?它可以被视为辅助setter,而不是接口的一部分,因为它处于隐式实现情况中.
更新:作为奖励,看似令人困惑,在我看来不太正确的编译错误,您收到的是以下内容:
访问者的可访问性修饰符必须比属性Connection1.ConnectionString更具限制性
请问,更严格的比private
,怎么......什么?
Dam*_*ver 64
调用显式接口成员的唯一方法是将对象强制转换为正确的接口,然后在该接口上调用该成员.但是一旦你投了IConnection
,IConnection.ConnectionString
就没有了.
所以没有办法调用这个私有的setter方法.
sup*_*cat 10
问题是当显式声明接口成员时,编译器会生成一个private
具有"不可发音"名称的实现,并且不提供代码(即使在实现类中)引用该实现的方法.
基本上,当一个人说void IFoo.Moo()
,一个人说不希望Moo
在类范围内定义一个名字; 因此,编译器不会.为了private set
工作,该成员必须是一个"可发音"的名称,并且该成员被明确实现的事实被视为一个人不希望该名称的指示Moo
.
在实践中,这里的补救措施可能与许多其他情况相同,在这种情况下,必须有一个名称可以发音的接口实现,但不会在其名称下公开公开:声明一个接口实现,除了链接到其他成员之外什么都不做具有适当的可访问性,例如,如果派生类不应该能够影响值的值:
private readonly int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
Run Code Online (Sandbox Code Playgroud)
或者,如果派生类应该能够影响它,或者
protected int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
Run Code Online (Sandbox Code Playgroud)
要么
private int _foo = whatever;
protected virtual int setFoo(int value) { _foo = value; }
protected virtual int getFoo() { return _foo; }
public int IFOO.Foo { get {return getFoo();}}
Run Code Online (Sandbox Code Playgroud)
在vb.net中,接口可以使用受保护的类成员实现,但C#不提供此类工具.
我认为问题的核心是界面只有它所需要的东西.如果它不公开,它自然不是界面的一部分.因此,当您显式实现接口时,它不存在.
在隐式的情况下,您的代码适合接口,但不完全受其约束.如果需要,您可以添加更多内容.
获取有关原因的信息需要语言设计师来回答您.但是,对我来说似乎合乎逻辑:如果它不是接口的一部分,则无法在接口中实现/访问它.