gpt4 book ai didi

.net - .NET 中 API 突破性更改的权威指南

转载 作者:行者123 更新时间:2023-12-03 04:08:27 26 4
gpt4 key购买 nike

我想收集尽可能多的关于 .NET/CLR 中 API 版本控制的信息,特别是 API 更改如何破坏或不破坏客户端应用程序。首先,让我们定义一些术语:

API 变更 - 类型的公开可见定义的更改,包括其任何公共(public)成员。这包括更改类型和成员名称、更改类型的基类型、从类型的已实现接口(interface)列表中添加/删除接口(interface)、添加/删除成员(包括重载)、更改成员可见性、重命名方法和类型参数、添加默认值对于方法参数,添加/删除类型和成员的属性,以及添加/删除类型和成员的泛型类型参数(我错过了什么?)。这不包括成员团体的任何变化,或私有(private)成员的任何变化(即我们不考虑 Reflection)。

二元突破 - API 更改导致针对旧版本 API 编译的客户端程序集可能不会随新版本一起加载。示例:更改方法签名,即使它允许以与以前相同的方式调用(即:void 返回类型/参数默认值重载)。

源级突破 - API 更改导致编写的现有代码针对旧版本的 API 进行编译,可能无法使用新版本进行编译。然而,已经编译的客户端程序集像以前一样工作。示例:添加新的重载可能会导致之前明确的方法调用出现歧义。

源级安静语义更改 - 导致现有代码编写以针对旧版本的 API 进行编译的 API 更改悄悄改变其语义,例如通过调用不同的方法。然而,代码应该继续编译而不会出现警告/错误,并且以前编译的程序集应该像以前一样工作。示例:在现有类上实现新接口(interface),导致在重载解析期间选择不同的重载。

最终目标是对尽可能多的破坏性和安静语义 API 更改进行分类,并描述破坏的确切影响,以及哪些语言受到和不受影响。扩展后者:虽然一些更改普遍影响所有语言(例如,向接口(interface)添加新成员将破坏该接口(interface)在任何语言中的实现),但有些更改需要非常特定的语言语义才能发挥作用才能中断。这通常涉及方法重载,并且通常涉及与隐式类型转换有关的任何事情。即使对于符合 CLS 的语言(即那些至少符合 CLI 规范中定义的“CLS 消费者”规则的语言),似乎也没有任何方法可以在这里定义“最小公分母”——尽管我会很感激有人纠正我在这里错了 - 所以这将不得不逐个语言地进行。最感兴趣的自然是 .NET 自带的那些:C#、VB 和 F#;但其他的,如 IronPython、IronRuby、Delphi Prism 等也与此相关。它的极端情况越多,它就越有趣——像删除成员这样的事情是不言而喻的,但是例如之间的微妙交互。方法重载、可选/默认参数、lambda 类型推断和转换运算符有时会非常令人惊讶。

启动此操作的几个示例:

添加新的方法重载

种类:源级中断

受影响的语言:C#、VB、F#

更改前的API:

public class Foo
{
public void Bar(IEnumerable x);
}

更改后的API:
public class Foo
{
public void Bar(IEnumerable x);
public void Bar(ICloneable x);
}

示例客户端代码在更改前工作并在更改后损坏:
new Foo().Bar(new int[0]);

添加新的隐式转换运算符重载

种类:源级中断。

受影响的语言:C#、VB

不受影响的语言:F#

更改前的API:
public class Foo
{
public static implicit operator int ();
}

更改后的API:
public class Foo
{
public static implicit operator int ();
public static implicit operator float ();
}

示例客户端代码在更改前工作并在更改后损坏:
void Bar(int x);
void Bar(float x);
Bar(new Foo());

注意:F# 没有被破坏,因为它没有对重载运算符的任何语言级别支持,既不显式也不隐式 - 两者都必须直接调用为 op_Explicitop_Implicit方法。

添加新的实例方法

Kind:源级安静语义变化。

受影响的语言:C#、VB

不受影响的语言:F#

更改前的API:
public class Foo
{
}

更改后的API:
public class Foo
{
public void Bar();
}

遭受安静语义更改的示例客户端代码:
public static class FooExtensions
{
public void Bar(this Foo foo);
}

new Foo().Bar();

注意:F# 没有损坏,因为它没有对 ExtensionMethodAttribute 的语言级别支持,并且需要将 CLS 扩展方法作为静态方法调用。

最佳答案

更改方法签名

种类:二进制中断

受影响的语言:C#(最有可能是 VB 和 F#,但未经测试)

更改前的 API

public static class Foo
{
public static void bar(int i);
}

更改后的 API
public static class Foo
{
public static bool bar(int i);
}

更改前工作的示例客户端代码
Foo.bar(13);

关于.net - .NET 中 API 突破性更改的权威指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1456785/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com