【问题标题】:C#: Interface implementationC#:接口实现
【发布时间】:2012-11-23 06:13:00
【问题描述】:

我在我正在经历的代码库中找到了以下实现

Interface IOrder
{
GetSubmittedOrder();
CreateOrder();
GetExistingOrder();
}

Class Order : IOrder
{
BuildSpecialOrder();
AddSpecialOrderParameters();
IOrder.GetSubmittedOrder();
IOrder.CreateOrder();
IOrder.GetExistingOrder();
}

现在,当我们想从这个Order对象访问最后三个方法时,我们需要做如下声明

IOrder objOrder = new Order();

创建这样的实现的原因(优点)是什么?这种做法有具体的名称吗?

注意:如果这更适合程序员,请告诉我。

【问题讨论】:

    标签: c# oop design-patterns inheritance


    【解决方案1】:

    我会说这是 explicit interface implementation 的错误用法。这基本上意味着这些方法在公共类合同中不可见。这就是为什么您必须首先将对象转换为接口类型(您正在使用隐式转换)。你也可以这样做:

    var order = (IOrder)order;
    order.GetExistingOrder();
    

    通常在类方法与接口方法发生冲突时使用,或者当类实现了两个具有相同方法(但用途不同)的接口时。

    应谨慎使用,因为它可能表明您的班级责任过大(应分成较小的班级)。

    【讨论】:

    • 第三种使用场景是当您需要实现接口,但您不想支持该接口中的某个方法时。例如,System.Array 实现了ICollection,但Add 方法会抛出NotSupportedException,因为数组是固定大小的。因此,不使用普通的public 方法实现Add 是很自然的(因为它是一个总是抛出的方法)。
    • 没有错。这不是您通常使用显式接口实现的方式。在我看来,创建类的开发人员不确定该类是否应该实现该接口(因为他隐藏了方法)
    • 或者只是当您不希望接口方法污染托管类的公共面时。
    • @JeppeStigNielsen:这违反了 Liskovs 替代原则(但如果您真的必须这样做,这仍然可能是最好的方法)。
    • @jgauffin 肯定违反了 Liskov!但是 BCL 使用它。 (但它来自IList,而不是ICollection。)
    【解决方案2】:

    它叫explicit interface implementation

    用于区分具体接口的实现,以防多个接口实现的方法名称冲突。

    interface IOrder
    {
      GetSubmittedOrder();
      CreateOrder();
      GetExistingOrder();
    }
    
    interface ISpecificOrder
    {
      GetSubmittedOrder();
      CreateOrder();
      GetExistingOrder();
    }
    
    Class Order : IOrder, ISpecificOrder
    {
      BuildSpecialOrder();
      AddSpecialOrderParameters();
    
      IOrder.GetSubmittedOrder();
      IOrder.CreateOrder();
      IOrder.GetExistingOrder();
    
      ISpecificOrder.GetSubmittedOrder();
      ISpecificOrder.CreateOrder();
      ISpecificOrder.GetExistingOrder();
    
    }
    

    【讨论】:

    • 不正确。同一个类方法可以用来实现所有同名的接口方法。这是默认行为。
    • @jgauffin 是的,你是对的。如果您希望不同的接口有不同的行为,应该选择显式接口实现。
    • @asif:你的意思不是很明确吗?
    【解决方案3】:

    考虑适配器模式Wiki - Adapter pattern
    当与其他应用程序或应用程序的一部分(以及许多其他需求)通信时,您不想绑定类型,因为它将在运行时决定,您可以使用这种类型的对象声明。这将创建接口类型的对象,但会分配所需类型的内存(嵌套在 switch case 中或由其他函数返回)。

     IOrder objOrder = new Order();
    

    另一个问题是关于接口的隐式和显式实现。两者都可以在不同的场景中使用。您可以从 google 找到更多详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 2012-02-01
      • 1970-01-01
      相关资源
      最近更新 更多