一个明确的指南,在.NET API破变化 [英] A definitive guide to API-breaking changes in .NET

查看:113
本文介绍了一个明确的指南,在.NET API破变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想收集尽可能多的信息尽可能有关API版本的.NET / CLR,具体API变更怎么办还是不破客户端应用程序。首先,让我们来定义一些术语:

I would like to gather as much information as possible regarding API versioning in .NET/CLR, and specifically how API changes do or do not break client applications. First, let's define some terms:

API的变化 - 在类型的公开的定义,包括其任何公共成员的变化。这包括更改类型和成员的名字,改变类型的基本类型,添加/删除从一个类型实现的接口列表界面,添加/删除成员(包括过载),改变成员可见,重命名方法和类型的参数,将默认值方法的参数,添加/删除的类型和成员的属性,并添加/删除的类型和成员泛型参数(我错过了什么?)。这还不包括在成员机构的任何变化,还是私有成员的任何更改(即不考虑反射)。

API change - a change in the publicly visible definition of a type, including any of its public members. This includes changing type and member names, changing base type of a type, adding/removing interfaces from list of implemented interfaces of a type, adding/removing members (including overloads), changing member visibility, renaming method and type parameters, adding default values for method parameters, adding/removing attributes on types and members, and adding/removing generic type parameters on types and members (did I miss anything?). This does not include any changes in member bodies, or any changes to private members (i.e. we do not take into account Reflection).

二进制级别的突破 - 一个API的变化是导致编译反对的API可能无法加载新版本较旧版本的客户端组件。例如:改变方法的签名,即使它可以被称为相同的方式和以前一样(即:无效,返回式/参数的默认值重载)。

Binary-level break - an API change that results in client assemblies compiled against older version of the API potentially not loading with the new version. Example: changing method signature, even if it allows to be called in the same way as before (ie: void to return type / parameter default values overloads).

源代码级的突破 - 一个API的变化导致在现有的code写的编译针对API可能无法在新版本编译的旧版本。已编译的客户端组件不过像以前一样工作。例子:增加一个新的过载,可能导致歧义方法调用,均明确previous

Source-level break - an API change that results in existing code written to compile against older version of the API potentially not compiling with the new version. Already compiled client assemblies work as before, however. Example: adding a new overload that can result in ambiguity in method calls that were unambiguous previous.

源代码级的安静的语义变化 - 一个API的变化导致在现有的code编写编译对API的旧版本悄悄地改变它的语义,如通过调用一个不同的方法。在code然而,应该继续编译没有警告/错误,并且previously编译的程序应该像以前一样工作。例如:实现对现有类,结果在一个不同的过载一个新的接口重载解析过程中被选为

Source-level quiet semantics change - an API change that results in existing code written to compile against older version of the API quietly change its semantics, e.g. by calling a different method. The code should however continue to compile with no warnings/errors, and previously compiled assemblies should work as before. Example: implementing a new interface on an existing class that results in a different overload being chosen during overload resolution.

的最终目标是catalogize尽可能多的打破和安静的语义API的变化成为可能,并描述破损的确切疗效,且语言,并不受它的影响。为了扩大对后者:虽然有些变化会影响所有的语言普遍(如添加新成员到接口将打破在任何语言中的接口的实现),有的要求非常具体的语言语义进入发挥拿到一个破发。这最通常涉及方法重载,并且在一般情况下,任何事情必须做隐式类型转换。似乎没有任何办法来定义最小公分母在这里即使是CLS符合规范的语言(即那些至少为CLS消费,如CLI规范中定义的规则一致) - 虽然我会AP $所以这将必须通过语言去语言 - 如果有人纠正我,是错在这里p $ pciate。那些最关心的自然是那些带有.NET开箱:C#,VB和F#;但其他如IronPython,IronRuby的,德尔福棱镜等也与此有关。角落情况下,它的多,更有趣的将是 - 比如移除成员pretty的不言而喻的,但如之间微妙的相互作用方法重载,可选/默认参数,拉姆达类型推断,和转换操作符可以是非常令人惊讶的时候。

The ultimate goal is to catalogize as many breaking and quiet semantics API changes as possible, and describe exact effect of breakage, and which languages are and are not affected by it. To expand on the latter: while some changes affect all languages universally (e.g. adding a new member to an interface will break implementations of that interface in any language), some require very specific language semantics to enter into play to get a break. This most typically involves method overloading, and, in general, anything having to do with implicit type conversions. There doesn't seem to be any way to define the "least common denominator" here even for CLS-conformant languages (i.e. those conforming at least to rules of "CLS consumer" as defined in CLI spec) - though I'll appreciate if someone corrects me as being wrong here - so this will have to go language by language. Those of most interest are naturally the ones that come with .NET out of the box: C#, VB and F#; but others, such as IronPython, IronRuby, Delphi Prism etc are also relevant. The more of a corner case it is, the more interesting it will be - things like removing members are pretty self-evident, but subtle interactions between e.g. method overloading, optional/default parameters, lambda type inference, and conversion operators can be very surprising at times.

几个例子的kickstart这样的:

A few examples to kickstart this:

种类:源代码级别的突破

Kind: source-level break

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

Languages affected: C#, VB, F#

变更前API:

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

变更后的API:

API after change:

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

样本客户code修改前的工作和之后破:

Sample client code working before change and broken after it:

new Foo().Bar(new int[0]);

添加新的隐式转换操作符重载

类:源代码级别的突破

Adding new implicit conversion operator overloads

Kind: source-level break.

受影响的语言:C#,VB

Languages affected: C#, VB

语言不会受到影响:F#

Languages not affected: F#

变更前API:

public class Foo
{
    public static implicit operator int ();
}

变更后的API:

API after change:

public class Foo
{
    public static implicit operator int ();
    public static implicit operator float ();
}

样本客户code修改前的工作和之后破:

Sample client code working before change and broken after it:

void Bar(int x);
void Bar(float x);
Bar(new Foo());

注:F#不破的,因为它没有任何的语言水平支持重载运营商,无论是显性还是隐性 - 都有直接称为 op_Explicit op_Implicit 的方法。

类:源代码级别的安静语义变化

Kind: source-level quiet semantics change.

受影响的语言:C#,VB

Languages affected: C#, VB

语言不会受到影响:F#

Languages not affected: F#

变更前API:

public class Foo
{
}

变更后的API:

API after change:

public class Foo
{
    public void Bar();
}

样本客户code,它受到一个安静的语义变化:

Sample client code that suffers a quiet semantics change:

public static class FooExtensions
{
    public void Bar(this Foo foo);
}

new Foo().Bar();

注:F#不破,因为它不具备 ExtensionMethodAttribute 语言层面的支持,并要求CLS扩展方法被称为静态方法。

Notes: F# is not broken, because it does not have language level support for ExtensionMethodAttribute, and requires CLS extension methods to be called as static methods.

推荐答案

类:二进制层次的休息

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

Languages affected: C# (VB and F# most likely, but untested)

变更前API

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

变更后的API

API after change

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

样本客户code修改前的工作

Sample client code working before change

Foo.bar(13);

这篇关于一个明确的指南,在.NET API破变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆