它确实使我受益最大

时间:2021-11-11 06:15:57

不按时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求列位看官老爷们轻喷,如感受我翻译有问题请挪步原博客地点

本博文翻译自:

在这篇文章中,请您和我一起浏览C#的各类版本,并分享每个版本中我最喜欢的特性。我将在强调实用性的同时展示其长处。

C#我最喜欢的成果 - V1至V7 C#1.0版本

C#1.0版本(ISO-1)真的是一种非常无趣的对象,没有什么出格令人兴奋的对象,而且它缺少很多开发者喜欢的语言。然而,有一种特另外特征,我认为是我最喜欢的。- 隐式和显式接口实现。

接口一直在使用,并且在现代的C#中仍然很风行。以下面的IDateProvider接口为例。

public interface IDateProvider { DateTime GetDate(); }

没有什么特另外,此刻设想两个实现 - 此中第一个隐式实现如下:

public class DefaultDateProvider : IDateProvider { public DateTime GetDate() { return DateTime.Now; } }

第二个显示实现是这样的:

public class MinDateProvider : IDateProvider { DateTime IDateProvider.GetDate() { return DateTime.MinValue; } }

注意显式实现如何省略访谒修饰符。别的,要领名称被写为IDateProvider.GetDate(),,它将接口名称作为限定符的前缀。

上面两个例子使实现越发明确

显式接口实现的一个简洁之处是,它强制用户依赖于接口。显式实现接口的类的实例东西没有可用的接口成员 - 而是必需使用接口自己。

但是,当您将其声明为接口或将此实现作为预期接口的参数通报时,成员将按预期可用。

当它强制使用接口时,这一点出格有用。通过直接使用接口,您不会将代码耦合到底层实现。同样,显式接口实现措置惩罚惩罚定名或要领签名的模糊性 - 并使单个类可以实现具有不异成员的多个接口。

Jeffery Richter在他的书 CLR via C#中警告我们关于显式接口的现。两个主要的存眷点是,当转换到显式实现的接口和要领时,值类型被装箱,而派生类型不能挪用它们。

请记住,装箱和拆箱会带来特别能耗,和所有的编程一样,您应该评估测试用例以确定适合该事情的工具。

C#2.0版本

作为参考,我将列出C#2.0(ISO-2)的所有成果。

匿名要领

协变和逆变

泛型

迭代器

可空类型

局部类型

我最喜欢的成果是介于泛型和迭代器之间,我选择了泛型,下面我来说说原因。

对我来说这是一个非常困难的选择,我最终决定了泛型,因为我相信我比写迭代器更频繁地使用泛型。很多SOLID编程原则都是通过在C#中使用泛型来优化的,同样它也有助于连结代码的简洁。不要误解我的意思,我确实写了很多迭代器,这是一个值得在你的C#中给与的特性!

让我们更详细地看看泛型。

编者注: 学习如何使用 在C#中使用泛型来提高应用措施的可维护性。

泛型介绍: .NET Framework引入了类型参数的观点,这使得可以设计类和要领来推迟一个或多个类型的规范,直到类或要领被客户端代码声明和实例化为止。

让我们设想一下,我们有一个名为DataBag的类,可以作为一个数据包。它可能看起来像这样:

public class DataBag { public void Add(object data) { // 为了简便起见,我们省略了... } }

乍一看,这似乎是个很棒的主意,因为您可以在这个数据东西包的实例中添加任何对象。但当你真正思考这意味着什么时,这可能是相适时人担心的。

所有添加的内容都隐式地转到了System.Object。别的,如果添加了值类型,则会产生装箱。这些是您应该注意的性能考虑事项。

泛型解决了这一切,,同时也增加了类型安适性。让我们改削前面的例子,在类中包罗一个类型参数T,并注意要领签名的变革。

public class DataBag { public void Add(T data) { // 为了简便起见,我们省略了... } }

此刻,例如,DataBag实例只允许使用者添加DateTime实例。类型安适,没有类型强制转换或装箱的世界是美好的。

泛型类型参数也可以被限制。泛型约束是强大的,允许有限范畴的可用类型参数,因为它们必需遵守相应的约束。有几种要领可以编写泛型类型参数约束,请参考以下语法:

public class DataBag where T : struct { /* T 是值类型*/ } public class DataBag where T : class { /* T 可以是类接口等引用类型*/ } public class DataBag where T : new() { /* T 必需有无参结构函数 */ } public class DataBag where T : IPerson { /* T 担任IPerson */ } public class DataBag where T : BaseClass { /* T 来源于BaseClass */ } public class DataBag where T : U { /* T担任U, U也是泛型类型参数。 */ }