每个界面都明确实现? (涉及IoC)

时间:2014-09-08 14:45:04

标签: c# inversion-of-control explicit-interface

我非常清楚这个问题可能已经发布过了。然而,在这种情况下IoC的参与以及很多代码我已经看到我在新公司的一位同事提出了这个问题。

情景:

在一个产品的代码库中,这个同事构建的每个接口都是明确实现的。整个应用程序是通过结构图构建的,但在某些地方使用具体类型并像这样投射

((IInterface)concreteClass).SomeMethod()

背景:

那位同事在询问了显式实现所有接口的内容后向我解释说,他们最近引入了StructureMap,很多人仍然会使用具体的类型。所以从本质上讲,它是一种“教育”公司员工的手段。

我对此事的看法:

首先,几年前已经完成了对StructureMap的切换,虽然这有点强制使用接口,但我认为这不是正确的方法。我看到它的方式,知道具体类型的人可以看到实现,并轻松地看到我上面显示的...只是投下它。清晰的通信或编码惯例会使这更好。如果使用IoC而没有具体的类,那么显式地实现接口就完全没用了。

我也听说这可能会破坏继承,但不知道一个例子。我也看到 Jon Skeet 有点不鼓励以上面提到的方式使用它,而是打算使用它的方式,比如IEnumerable<>和其他名字冲突。

任何人都可以为我解释这件事。优点和缺点(虽然我非常偏向于没有这样做,因此我的帖子在这里),尤其是为什么这样或那样的原因。

谢谢!

编辑:我非常清楚这不是对错,也不是真正的答案。这是了解每种方法缺陷的更多问题。为什么我会在一种情况下使用另一种方法呢?

2 个答案:

答案 0 :(得分:0)

这篇文章可能是一个很好的起点:Why I use explicit interface implementation as a default implementation technique

最初我并没有明确地实施接口,但我不得不承认作者提出了一些非常好的观点。

UPDATE :在下面的评论中,OP声明显式实现会破坏继承,因为您无法覆盖派生类型中的接口实现。我不确定我是否正确地解决了这个问题:

public interface IFooable
{
     void Foo();
     void FooAgain();
}

public class Blah: IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Blah'!");
     }

     void IFooable.FooAgain() {}
}

public class Bar: Blah, IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Bar'!");
     }
}

public static void Main()
{
   var fooList = new List<IFooable>();
   fooList.Add(new Blah());
   fooList.Add(new Bar());

   foreach (var fooable in fooList) //Outputs "Hi from 'Blah'!" / "Hi from 'Bar'!"
       fooable.Foo();

   Console.ReadLine();
}

答案 1 :(得分:0)

显式接口实现有两个主要的潜在优势:

  1. 单个类可以实现两个具有冲突方法签名的接口,并且每个接口都有微妙的不同实现。这种情况很少发生,按需而不是默认情况下通常不是问题。
  2. 您可以“隐藏”某些您不希望人们使用的方法,除非在特定的上下文中。 接口隔离原则鼓励我们不向消费者公开他们不太可能需要的方法。
  3. 使用#2的一个很好的例子是实体框架上下文避免直接暴露其底层ObjectContext的方式(因为大多数人不应该在他们的代码中使用它),但是仍然可以使这个属性可用您将上下文转换为IObjectContextAdapter

    就贵公司而言,听起来他们正试图利用#2,但出于错误的原因。他们希望隐藏方法实现,不是因为不希望使用该方法,而是因为他们期望它被使用 - 而且当它们希望它会鼓励开发人员将它们的代码与具体类型分离。您的代码示例表明它缺少标记 - 开发人员仍在实例化具体类型,然后将其转换为访问接口方法。