我正在寻找一种简洁的方法来对我的代码库进行增量更新,而不会破坏向后兼容性。这可能意味着向类添加新成员,或更改现有成员以提供其他功能。有时我需要更改一个成员,以致它会破坏现有代码(例如重命名方法或更改其返回类型),所以我不想在发货后触摸任何现有类型。
我目前设置的方式是通过继承和多态来创建一个扩展该类之前“版本”的新类。
这种方法的工作方式是根据StatusResult
属性的实际值创建StatusResultVersion3
的适当版本(例如ProtocolVersion
),并将其作为{的实例返回{1}}。
因为.NET似乎没有类版本控制的概念,所以我必须自己编写:将版本号附加到类名的末尾。这无疑会让你畏缩。我可以很容易地想象自己在放大图表后睁大眼睛。但它的确有效。我可以添加新成员并覆盖现有成员,而不会引入任何代码更改。
有没有更好的方法来修改我的课程?
答案 0 :(得分:1)
在考虑现有代码和程序集更新时,通常有两种方法:
对于非破坏性更改,这是一种很好的方法,您可以简单地重载函数以提供新参数等.Visual Studio有一些非常先进的unit testing capabilities,使您的回归测试相对容易和自动化。
如果您的更改将开始破坏,例如重写某些实用程序的工作方式,那么就应该开始新的程序集版本了。 .NET非常适合使用汇编版本。您可以将版本化程序集部署到不同的文件夹,以便现有代码可以继续引用旧版本,而新代码可以利用新版本中的功能。
答案 1 :(得分:1)
接口的问题在于,一旦发布,它们基本上就是一成不变的。引用Anders Hejlsburg:
...就像在界面中添加方法一样。在发布接口之后,它实际上是不可变的,因为它的任何实现都可能具有您要在下一个版本中添加的方法。所以你必须改为创建一个新界面。
因此,您永远不能只更新界面,您需要创建一个全新的界面。当然,您可以使用单个类实现两个接口,因此与(比方说)多态类相比,您的可维护性工作量相当低,其中您的代码将随着时间推移在多个类之间展开。
多个接口还允许您以类不能的方式删除方法(当然,您可以弃用它们,但在几次迭代后可能会导致非常嘈杂的智能感知)
我个人倾向于在每个程序集版本中拥有完全独立的界面版本。
也就是说......
interface IExample
{
String DoSomething();
}
interface IExample
{
void DoSomethingElse();
}
你如何在幕后实现它们取决于你,但很可能它是相同的类,有不同的方法做类似的工作(否则,为什么使用相同的接口?)
所有旧代码都应引用0.1.x.x
,新代码将引用0.2.x.x
。关于唯一的问题是当您发现(比方说)安全漏洞并且需要将修复程序反向移植到早期版本时。这是一个体面的VCS进入的地方(个人偏好是TFS,但SVN或支持分支/合并的任何其他东西都可以)。
将0.2
分支中的修补程序合并回0.1
分支,然后重新编译以生成(比方说)0.1.1.0
。
只要你坚持这样的过程:
这会给你:
答案 2 :(得分:0)
OP解决了他的问题,如this comment所示:
最后,我使用了接口的想法,因为它允许我在一个类文件中保留多个版本的类成员。当我需要更新类时,我只需添加新接口,遮蔽已更改的成员,并更改某些方法的返回类型。由于多态性,这可以在不破坏向后兼容性的情况下工作。
答案 3 :(得分:0)
如果主要用于序列化,可以使用DataContractSerializers和DataAnnotations在.Net中实现。他们可以将对象的不同版本反序列化为同一个对象,以允许对同一个类的不同版本进行反序列化,从而使其无法映射的任何属性为空。