1

我正在追踪一个错误,我在 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有一个成员string PreviousContainerId { get; set; }

这个模式有什么作用?我知道您无法从继承子树外部获取/设置 ,除非PreviousContainerId您先将. 但我不明白你为什么想要这个。LayoutContentILayoutPreviousContainer

在对这种模式进行研究后,我发现这篇SO 帖子让我更加困惑。通过以这种方式实现它,它似乎类似于只拥有一个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{ /* ... */ }
}

我错过了什么吗?

4

2 回答 2

2

protected属性不能隐式或显式地实现接口属性。因此,如果您想从此类和派生类轻松直接访问,您需要一个protected属性和另一个显式实现接口的“隐藏”属性。

查看您的示例,可以考虑切换两个属性的角色,例如protected一个是自动属性,而实现接口的一个是指自动属性(而不是相反)。

你看到什么替代方案?如果这样做了(因此隐式实施),人们可以坚持使用单个属性public,但在这种情况下,该属性会暴露得更多,这显然是不希望的。

于 2014-06-04T20:48:23.470 回答
1

ILayoutPreviousContainer似乎是一个internal界面。所以对于外部用户SpecificLayoutControl来说,接口是不存在的,只有PreviousContainerId类上定义的属性。

通常的规则适用于是否应该是protectedpublic。我不会对此进行扩展,因为这似乎不是您的问题所在。

该类的作者已决定该属性应为protected. 但是,如果是protected,则它无法实现接口的属性,并且虽然外部用户看不到该接口,但在内部其他地方需要该接口。因此,他们像这样实现它,其中一个属性仅转发给另一个。

于 2014-06-04T20:50:07.183 回答