c# - 实现接口(interface)扩展属性(继承?)

标签 c# inheritance interface

我有一个必须解决的接口(interface)实现: 这是一个例子:

interface ISettingsBase
{
    string Name { get; set;}
    DateTime TimeStamp { get; set; }
}

public class SettingsBase : ISettingsBase
{
    public string Name { get; set; }
    public DateTime TimeStamp { get; set; }
}

interface IWorkerBase
{
    ISettingsBase Settings { get; set; }
}

public class WorkerBase: ISettingsBase
{
    public ISettingsBase Settings { get; set; }
}

interface IExtendedSettings : ISettingsBase
{
    string FilePath { get; set; }
}

interface IWorkerExtended : IWorkerBase
{
    // This configuration property should respect those of
    // the IWorkerBase and increase the features.
    IExtendedSettings Settings { get; set; }
}

public class WorkerExtended : WorkerBase, IWorkerExtended
{
    ...
    ...
    public IExtendedSettings Settings { get; set; }
}

问题是编译器告诉我 WorkerExtended 中存在错误,并且我不遵守 IWorkerBase.Settings 接口(interface)的实现。问题是我需要新的改进类也支持具有更多属性的配置。

最佳答案

interface IWorkerBase
{
    ISettingsBase Settings { get; set; }
}

interface IWorkerExtended : IWorkerBase
{
    IExtendedSettings Settings { get; set; }
}

这已经有问题了,因为 IWorkerExtended.Settings隐藏 IWorkerBase 需要的 Settings 成员。因此,IWorkerExtended 的实现者仍然必须提供原始的 Settings 成员(类型为 ISettingsBase),以便传递实现 IWorkerBase.

编译器会在这里警告你,因为这里正在隐藏这个成员。通常这样做会出错,所以你需要使用 new 键盘来表达你愿意这样做:

interface IWorkerExtended : IWorkerBase
{
    new IExtendedSettings Settings { get; set; }
}

请注意,这对实现者没有影响。因此,在实现该接口(interface)时,您必须提供两个 Settings 成员。您可以通过显式实现基本接口(interface)来做到这一点:

public class Worker : IWorkerExtended
{
    public IExtendedSettings Settings { get; set; }

    ISettingsBase IWorkerBase.Settings { get; set; }
}

原因很简单:Liskov substitution principle表示当 IWorkerExtendedIWorkerBase 的子类型时,则任何 IWorkerBase 类型的对象都可以被 IWorkerExtended< 类型的对象替换。现在考虑一下:

IWorkerBase baseWorker = GetExtendedWorker();
baseWorker.Settings = new SettingsBase(); // not extended

这只有在您可以将 SettingsBase 分配给 Settings 时才有效,这是类型 IWorkerBase 所保证的(因为 SettingsBaseISettingsBase 的子类型)。因此,为了使扩展工作人员可分配给基本工作人员类型,它需要保证您可以为其设置 ISettingsBase。但如果它只是实现 IWorkerExtended,您可以将更具体的扩展设置分配给 Settings

关于c# - 实现接口(interface)扩展属性(继承?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45488584/

相关文章:

多维矩阵的Java接口(interface)设计

c# - C# 中的后台线程

c# - Entity Framework 4 部分 SaveChanges

C++ 接口(interface)和继承

javascript - 是否可以将 typescript 接口(interface)导出为方法的输出?

java : Function objects as strategies

c# - 如何将一个c#文件包含到另一个c#文件中?

c# - 如何使用CefSharp获取网页加载的资源

C++:是否可以使用带有模板参数的动态绑定(bind)?

c++ - 派生类的模板类作为函数的参数 - 危险?