C# 我们可以用具有扩展方法的接口替换抽象类吗?
我们即将从头开始一个项目。根据设计讨论,我想带上这个话题 大多数时候,我看到抽象类只是用来提供一些具体方法的默认/通用行为 因此,我考虑将这些具体方法定义为我将要开发的接口的扩展方法,以代替抽象类C# 我们可以用具有扩展方法的接口替换抽象类吗?,c#,C#,我们即将从头开始一个项目。根据设计讨论,我想带上这个话题 大多数时候,我看到抽象类只是用来提供一些具体方法的默认/通用行为 因此,我考虑将这些具体方法定义为我将要开发的接口的扩展方法,以代替抽象类 有人能指导我的设计决策吗。如果你不同意我的观点,请用我们可能面临的情况/问题来证明你的论点。因此,这将提高我的知识。这两种方法非常不同 通过使用抽象类和抽象/虚拟方法,可以允许派生类重写扩展方法所不具备的行为。扩展方法归根结底是扩展,它们不是类型的一部分,当有人检查API和类型提供的功能时,很难发现它
有人能指导我的设计决策吗。如果你不同意我的观点,请用我们可能面临的情况/问题来证明你的论点。因此,这将提高我的知识。这两种方法非常不同 通过使用抽象类和抽象/虚拟方法,可以允许派生类重写扩展方法所不具备的行为。扩展方法归根结底是扩展,它们不是类型的一部分,当有人检查API和类型提供的功能时,很难发现它们
第二点,为您自己创建的类型创建扩展方法并不是那么合乎逻辑。使用基本抽象类可以保持层次结构清晰,并保持模型对重写行为的修改保持打开状态。基本上,您可以扩展每个类或接口-Linq扩展方法没有其他功能 但是,您不能直接在接口中定义这些方法,您始终需要一个包含这些扩展的静态公共类 为了回答您的问题,我怀疑在扩展方法中定义默认行为是否是一件好事,因为它完全压缩了接口的实际意图。当创建扩展方法时,该扩展类/接口的所有实例都共享这些方法,因此您要做的是说我接口的每个实例都可以被视为我的抽象类 话虽如此,接口的行为和类的实际处理应该有所不同。两者的混合最终会使你的设计变得相当复杂 接下来,通过定义扩展mtehods,您可以完全绕过继承。那么,如果要覆盖默认行为,该怎么办?如果将它们定义为新的或任何不同的wewird解决方案,您将不知所措,因为您的设计根本不允许继承
从我的观点来看,最后一点是,您应该对无法控制的类使用扩展方法。但是,当您可以修改代码时,您可能不会使用它们 在C中引入扩展方法是因为有一个非常特殊的需求 在设计LINQ时,他们意识到他们不想创建一个包含所有已知LINQ方法(如Where或Select)的新接口,因为这意味着任何可枚举或集合实现都需要实现它 上面提到的事实有一个重要的缺点:它需要大量更改基类库中许多类的源代码,任何实现自定义集合的第三方库或项目都无法利用LINQ 然后,他们考虑了一种可以直接使用迭代器(即IEnumerator)的方法,这种方法可以与任何IEnumerable兼容,而无需修改任何现有代码,只需向新的程序集成员添加新代码 他们发明了扩展方法,可以像静态方法一样实现,并且可以作为给定类型的实例成员 自从扩展方法出现以来,它们已经在许多其他场景中实现,但它们始终涵盖以下两个用例: 我有一个庞大的代码库,我想为所有类型提供一个功能,派生类或实现其他类型的接口,而不必修改它们,在大量代码中实现一个新接口,从而增加引入新错误的机会 我没有一些项目的源代码,我想扩展一些类型以支持一些新方法 这些用例之外的任何东西都是对扩展方法的滥用
扩展方法不能替代常规的基于类的面向对象编程。Linq?扩展方法与linq无关。@user3185569这只是一个示例。但是,Linq方法A与扩展方法相关联。@HimBromBeere如果我可以选择将多个响应标记为答案,我会将您的响应也标记为答案,但不幸的是,我们没有。谢谢你的解释。我已经编辑了很多段落来分隔你的文章。下一次是你的工作!如果一个问题是由一段很多行组成的,那就很难理解了。谢谢。@Matíasfidelizer谢谢你的帮助。在下一篇文章中,请记住,为自己设计的接口创建扩展方法非常有用,如果
该方法的xact实现不依赖于底层类型,因为这使得多次实现同一接口更便宜,需要实现的方法更少。感谢您提到LINQ。很高兴知道。特别感谢你关于未知源代码的第二点。在我最近的一次采访中,有人这样问我,你会如何处理一些未知的源代码?当我说我不知道的时候,面试官问我关于推广方法的问题,并告诉了我你在第二点中所说的确切内容。