扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:佚名 来源:Microsoft 2007年11月14日
关键字:
现在,编译器在检测是否存在 IDisposable 接口时,无论迭代程序类型是否实现 IEnumerator,都将调用 Dispose 方法(如果已实现)。在下面的示例中,Visual C# .NET 2002 编译器未调用 Dispose 方法,但 Visual C# .NET 2003 编译器调用了该方法:
abstract class Base class Derived: Base, IDisposable class MyClass |
当 foreach 语句在某个对象集合中使用迭代时,它将执行 GetEnumerator 方法并接收转换为 Base 类型的 Derived 实例作为它的迭代程序类型。当然,Base 类型无需为了调用它的 Current 和 MoveNext 方法而实现 Ienumerator 接口。在早期编译器中,Derived 类型的 Dispose 方法不被调用,因为它不实现 IEnumerator,并且类 Base 对于实现 Idisposable 不是静态已知的。在新的编译器中,Dispose 方法被调用,因为编译器在所有 foreach 语句的迭代程序类型中检查是否存在 Idisposable 接口。由于 GetEnumerator 调用的结果是一个转换为 Base 类型的 Derived 类型,并且由于 Derived 类型实现 Idisposable 接口,因此编译器动态检查 Idisposable 接口是否存在,会导致对 Dispose 方法的调用。
属性声明的改变
ECMA C# 标准明确禁止为相应的属性创建获取和设置函数。实际上,C# 编译器将属性声明转换为获取和设置函数,以便不支持属性的语言也可以访问数据。因此,下面的代码是无效的,因为编译器会产生 get_Prop 和 set_Prop 方法,而这两个方法与用户声明的方法发生冲突:
public class MyClass set // 现在属于非法函数 // 现在属于非法函数 |
以前,C# 编译器允许创建此类函数,显然这是一个软件错误。2003 版的 C# 编译器纠正了这个错误。
作为此编译器错误纠正的必然结果,C# 编译器将不再允许显式创建生成属性的获取和设置函数(如果将属性定义为接口实现的结果)。在下面的示例中,2003 版的 C# 编译器不再允许在 Derived 类中显式实现 IMyInterface.get_Prop 和 IMyInterface.set_Prop 方法:
interface IMyInterface public class Derived : IMyInterface set // 非法 // 非法 |
其他改变
C# 编译器的早期版本允许不兼容地使用属性。2003 版的 C# 编译器已经纠正了这些用法,因此更符合 ECMA 规范。首先是对 C# 编译器进行了纠正,不允许在其参数列表中使用未在属性类声明中声明为 public 的命名参数。例如,如果某个 AuthorAttribute 类是使用名为 authorName 的私有字段创建的,则下面的语句在 C# 编译器的早期版本中是允许的,但在 C# 2003 编译器中却会导致错误:
[Author(authorName="microsoftuser")] public class MyClass { } |
第二,ObsoleteAttribute 现在可以应用到运算符,这样程序员就可以使重载的运算符函数失效。最后,编译器以前对于无法识别的属性位置常常生成一个错误,而现在则根据 ECMA C# 规范的要求只生成一个警告。
另外,C# 编译器以前接受用户定义的移位运算符参数(<< 和 >>),而根据 ECMA C# 规范,这些参数是无效的。例如,移位运算符以前可以按以下方式进行声明,即将封装类的类型声明为第二个操作数:
public class MyClass { public static MyClass operator <<(int I, MyClass c) { } public static void Main() { } } |
按照规范,如果向左移位运算符被重载,则二进制运算符的操作数列表中的第一个参数必须为封装类型。同样,如果向右移位运算符被重载,则二进制运算符的操作数列表中的第二个参数必须为封装类型。下面的代码示例演示了向左移位运算符的正确声明方式:
public class MyClass { public static MyClass operator <<( MyClass c, int i) { } public static void Main() { } } |
最后,还加入了几个用于纠正编译器错误的修复,包括:
对显式赋值算法的纠正,使编译器对于符合 ECMA C# 规范的代码不再报错。
枚举类型现在可以转换为字符(详见 ECMA C# 规范中的说明)。
内部虚警告已被删除,因为内部虚函数无法在程序集外被重写。
小结
C# 编译器以不同的方式实现了几个功能,从而获得了比前一版更高的性能。但这些改进不会影响对代码的编译和执行:
在迭代字符串的元素时,foreach 语句现在使用字符串的索引器而非枚举器模式,这样使性能更佳。
现在,C# 编译器在处理浮点运算和十进制数学运算方面更严格地遵循 ECMA C# 规范。
几个软件错误已被修复,使控制流得到优化。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者