简体   繁体   English

显式接口实现与第二个实现

[英]Explicit interface implementaion with second implementation

I was tracking down a bug and I found this in the Avalon Dock 2.0 source code: 我正在追踪一个错误,我在Avalon Dock 2.0源代码中找到了这个:

 public abstract class LayoutContent : LayoutElement, /* ... */, ILayoutPreviousContainer
 {
    // ...
    [XmlIgnore]
    string ILayoutPreviousContainer.PreviousContainerId
    {
        get;
        set;
    }

    protected string PreviousContainerId
    {
        get { return ((ILayoutPreviousContainer)this).PreviousContainerId; }
        set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; }
    }
}

ILayoutPreviousContainer has a member string PreviousContainerId { get; set; } ILayoutPreviousContainer有一个成员string PreviousContainerId { get; set; } string PreviousContainerId { get; set; } string PreviousContainerId { get; set; } . string PreviousContainerId { get; set; }

What does this pattern accomplish? 这种模式有什么作用? I understand that you could not get/set the PreviousContainerId from outside the inheritance subtree unless you first cast the LayoutContent to an ILayoutPreviousContainer . 我知道除非您首先将LayoutContent ILayoutPreviousContainer转换为ILayoutPreviousContainer否则无法从继承子树外部获取/设置PreviousContainerId But I don't understand why you would want this. 但我不明白为什么你会想要这个。

Upon doing research about this pattern, I found this SO post which confused me some more. 在研究这种模式后,我发现这个SO帖子让我更加困惑。 By implementing it this way, it is seemingly similar to having just a virtual property that would be implemented in a convoluted way: 通过这种方式实现它,它看起来类似于只有一个virtual属性,它将以一种复杂的方式实现:

public class SpecificLayoutContent : LayoutContent, ILayoutPreviousContainer
{
     // override LayoutContent.PreviousContainerId since it casts 'this' to an ILayoutPreviousContainer
     // which will then call this property
     string ILayoutPreviousContainer.PreviousContainerId{ /* ... */ }
}

Am I missing something? 我错过了什么吗?

A protected property cannot implement an interface property, implicitly or explicitly. protected属性无法隐式或显式地实现接口属性。 So if you want easy direct access from this class and derived classes, you want one protected property and another "hidden" property which explicitly implements the interface. 因此,如果您希望从此类和派生类轻松直接访问,则需要一个protected属性和另一个显式实现该接口的“隐藏”属性。

Looking at your example, one could consider switching roles of the two properties, such that the protected one was an auto-property, and interface-implementing one was referring to the auto-property (and not the other way around). 看一下你的例子,可以考虑切换两个属性的角色,这样protected的属性就是一个自动属性,而实现一个属性的接口是指自动属性(而不是相反)。

What alternative do you see? 您看到了什么选择? One could stick to a single property if that was made public (so implementing implicitly), but in that case the property would be exposed much more which is apparently not desired. 如果将其public (因此隐式实施),可以坚持单一财产,但在这种情况下,财产将暴露更多,这显然是不希望的。

ILayoutPreviousContainer seems to be an internal interface. ILayoutPreviousContainer似乎是一个internal接口。 So as far as outside users of SpecificLayoutControl are concerned, the interface doesn't exist, and there is just the PreviousContainerId property defined on the class. 因此,就SpecificLayoutControl外部用户而言,接口不存在,并且只在类PreviousContainerId定义了PreviousContainerId属性。

The usual rules apply for whether that should be protected or public . 通常的规则适用于是应该protected还是public I won't expand on that, since it doesn't seem like that's what your question is about. 我不会对此进行扩展,因为这似乎不是你的问题所在。

The class's authors have decided that the property should be protected . 该班的作者已决定该财产应受到protected However, if it is protected , it cannot implement the interface's property, and although external users don't see that interface, internally that interface is required elsewhere. 但是,如果它protected ,则无法实现接口的属性,尽管外部用户看不到该接口,但在其他地方内部需要该接口。 So, they implemented it like this, where one property merely forwards to the other. 所以,他们像这样实现它,其中一个属性仅仅转发给另一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM