从类继承以保证向后兼容性

Posted

技术标签:

【中文标题】从类继承以保证向后兼容性【英文标题】:Inherit from class to garantee backward compatibility [closed] 【发布时间】:2016-02-13 13:17:03 【问题描述】:

从一个类继承以保证在重命名类时向后兼容是好的 c# 风格吗?例如,如果在脚本中使用了类并且无法通过重构轻松重命名?

例如:

public class NewClass  // Implementation 

[Obsolete("Is obsolete, please use NewClass instead")]
public class OldClass : NewClass  // EMPTY! 

还是我错过了什么?

非常感谢

【问题讨论】:

为什么不更新旧类本身? Update 是什么意思?我只想重命名它,因为我喜欢清晰正确的代码。因此,在我的情况下,旧名称不再正确。 (以前有人把产品名放在类名中,重命名产品就打破了这个逻辑,也不再符合我们的代码约定) 是唯一改变的名字吗? 我从来没有遇到过这种情况,但这当然会增加一些开销。所以我尽量不要这样做。 您可以实现implicit 运算符来定义OldClassNewClass 之间的转换,而不是继承。但是asis 运算符将无法正常工作。 【参考方案1】:

我认为让标记类从旧类继承是对继承的不好使用。 NewClass 不是 OldClass 的特殊类型。事实上,OldClass 应该被删除,并且只为了兼容性而继续存在,这可能会在将来的某个时候被放弃。因此NewClass 实际上并不意味着专门化OldClass,而是替换它。

组成与委派

public class NewClass 
 
    // [...]
    public void SomeThing()
    
        // you move all your stuff to the new class
    
    // [...]


[Obsolete("Is obsolete, please use NewClass instead")]
public class OldClass 

    private NewClass newClass = new NewClass();

    // [...]
    public void SomeThing()
    
        // and delegate your old class calls to that.
        this.newClass.SomeThing();
    
    // [...]

为什么

因为否则你不能在未来的某个时候安全地删除它而不知道没有人以这种方式做某事

NewClass myObject = new OldClass();

更好:提取interface

对于未来,请考虑为您的公共 API 提供 interfaces 并尽可能返回这些 API。这使得交换实现更容易:

public interface ISomeClass

    void SomeThing();


public class NewClass : ISomeClass
 
    // [...]
    public void SomeThing()
    
        // you move all your stuff to the new class
    
    // [...]


[Obsolete("Is obsolete, please use NewClass instead")]
public class OldClass : ISomeClass

    private NewClass newClass = new NewClass();

    // [...]
    public void SomeThing()
    
        // and delegate your old class calls to that.
        this.newClass.SomeThing();
    
    // [...]

这是您的解决方案和我更喜欢的方式的混合,因为 NewClassOldClass 必须共享一个公共 API,但不能相互继承(它们处于同一级别的继承-层次结构)。

【讨论】:

你是对的。这一点很重要:OldClass myObject = new NewClass(); 所以我将重命名该类并修复每个将发生的错误。希望下次更新后所有客户都会满意。谢谢! :) 如果你没有注意到:我只是提供了一点编辑,指出你用例中接口的价值。 是的,我确实注意到了。我想了想,似乎也是一个很好的解决方案。谢谢! @nozzleman,在 OP 代码中,他清空了OldClass 并将代码移到了NewClass 中,并使OldClass 继承自NewClass。因此,您的示例 OldClass myObject = new NewClass(); 无法编译,因此这不是问题。 完美的解决方案是完全删除 OldClass。但是如果你需要一些向后兼容,OP 解决方案是相当不错的。 (这实际上取决于需要兼容的客户端代码如何使用 OldClass)

以上是关于从类继承以保证向后兼容性的主要内容,如果未能解决你的问题,请参考以下文章

Apollo Graphql:重命名模式以实现向后兼容性

Windows:如何解决缺少的过程入口点以实现向后兼容性? [复制]

兼容性测试

jQuery 对向后兼容性的支持如何?

Postgres-XL 向后兼容 PostgreSQL?

如何以向后兼容的方式向 DTO 添加属性?