简体   繁体   中英

Explicit interface implementaion with second implementation

I was tracking down a bug and I found this in the Avalon Dock 2.0 source code:

 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; } 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 . 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. By implementing it this way, it is seemingly similar to having just a virtual property that would be implemented in a convoluted way:

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. 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.

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).

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.

ILayoutPreviousContainer seems to be an internal interface. 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.

The usual rules apply for whether that should be protected or 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 . 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. So, they implemented it like this, where one property merely forwards to the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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