Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将所有参数、返回类型、类定义转换为使用接口_C#_Oop_Interface - Fatal编程技术网

C# 将所有参数、返回类型、类定义转换为使用接口

C# 将所有参数、返回类型、类定义转换为使用接口,c#,oop,interface,C#,Oop,Interface,我正在将我的所有参数、返回类型、类转换为所有用户接口,而不是IUser 除了维护这一点所需的额外代码之外,他们对这种方法有什么负面影响吗?这不是一种罕见的方法,尤其是如果你做了大量的模拟;但是,它在以下方面存在问题: 数据绑定支持(尤其是在向表中添加行时) xml序列化(包括comms WCF、asmx等)或一般基于契约的序列化 你需要弄清楚模仿etc的好处是否超过了这些问题。在大多数情况下,您可能使用IUser,但是(例如)在通信层,使用原始DTO可能比使用接口更简单 请注意,我将上述内容

我正在将我的所有参数、返回类型、类转换为所有用户接口,而不是IUser


除了维护这一点所需的额外代码之外,他们对这种方法有什么负面影响吗?

这不是一种罕见的方法,尤其是如果你做了大量的模拟;但是,它在以下方面存在问题:

  • 数据绑定支持(尤其是在向表中添加行时)
  • xml序列化(包括comms WCF、asmx等)或一般基于契约的序列化
你需要弄清楚模仿etc的好处是否超过了这些问题。在大多数情况下,您可能使用
IUser
,但是(例如)在通信层,使用原始DTO可能比使用接口更简单


请注意,我将上述内容应用于类。如果涉及结构,请记住,在大多数情况下,这也会涉及装箱。

避免使用
ISuck
前缀


< > >强>编辑< /强>:<代码> iSku约定是应用于类型名称的符号的一种表现形式。

总体上,这将给您所有与松耦合相关的优点,所以一般来说,我认为这是一个巨大的胜利。但是,既然你问了缺点,我可以想到以下几个小缺点:

  • 因为您同时拥有接口声明和至少一个实现(您已经提到了这一点,所以为了完整起见,我仅将其包括在内),所以涉及到更多的代码
  • 导航代码变得越来越困难,因为您不能直接进入定义来查看另一个方法的功能(尽管我被告知Resharper在这方面很有帮助)
  • 在某些情况下,合同中的内容可能不仅仅是语义,接口无法捕捉到这一点。BCL的经典示例是,如果实现IList,则每次添加项时都必须增加Count属性。但是,作为一名开发人员,界面中没有任何内容强迫您这样做。在这种情况下,抽象基类可能值得考虑
  • 当涉及到添加新成员时,接口是脆弱的。再一次,你可以

我曾经经历过这样一个阶段,但在实践中发现,对于贫血的数据对象(即POCO),不需要接口

在实践中,可以使用接口来定义行为契约,但不一定是属性契约


一般来说,我建议您让单元测试来指导您。如果整个应用程序中都有丰富的对象,那么很可能需要接口。如果您有POCO,您很可能只需要在控制器样式的类中使用它们。

接口是一件非常好的事情,但是将它们应用到所有工件上是过分的。特别是在java中,您将得到两个不同的文件(接口+实现)。所以(和往常一样),这要视情况而定:)

关于“接口或不接口”
  • 我不会让域对象有接口(例如用户)。在我看来,对于代码理解来说,这是相当混乱的(对于域对象来说,接口通常会定义getter方法)。最近,让单元测试就位并拥有域对象接口是一件非常痛苦的事情。我不得不模拟所有这些getter,将测试数据放入域对象模拟相当麻烦
  • 粗粒度服务和api接口的情况正好相反。对于他们,我从一开始就有一个界面
  • 在更多内部模块封装的场景中,我从没有接口开始,在一些代码演化之后(如果需要),做出反应并进行提取接口重构
接口工件名称的“I”前缀 我以前也使用Ixxx前缀,但现在我(很高兴)放弃了它,原因如下:

  • 在不断发展的代码库中,很难保持所有这些“I”命名约定,特别是当您大量重构(提取接口、折叠接口等)时
  • 对于客户端代码,无论类型是基于接口还是基于类,它都应该是透明的
  • “I”会让你对良好的接口和类名感到懒惰
      与其说是缺点,不如说是警告。您会发现,为了实现良好的组件去耦合,您需要使用依赖项注入框架(也就是说,如果您希望保持理智,并且对接口映射到什么有某种概念的话)

      另外,非平凡类有时会自然地转换为多个接口。当您有公共静态方法(即
      User.CreateAdminUser
      )时,尤其如此。您还将发现,很难获得一个保存状态和执行操作的接口。一个接口要么是一个,要么是另一个,这通常更为自然


      如果你在这个过程中陷入困境,一定要花一分钟的时间研究一下你试图实现的合适范例。很可能以前有人已经解决了这个特殊的设计模式。考虑到这是一项重大的重构工作,您最好多花点时间,好好地完成它。

      我们今晚一直在喝酒,是吗?.NET开发人员希望接口以I开头,这是官方的.NET命名约定的一部分。一个好的API是一个没有任何意外的API,它的一切看起来和行为都像你期望的那样。+1优点-我没有想过数据绑定。至少在WPF中,这可以通过使用抽象基类而不是接口来缓解。但是,总的来说,我想说的是松耦合的优势,它不仅仅是模仿,尽管它也包括模仿。我完全同意你的第二点。我曾经有过非常糟糕的代码库经验,它有太多的抽象,所有的东西和它的狗都被抽象成一个接口。是朱