C# 语言习惯

一、使用属性而不是可访问的数据成员

二、使用运行时常量(readonly)而不是编译时常量(const)

  1. C# 有两种类型的常量:编译时常量和运行时常量。

  2.尽量使用运行时常量,而不是编译时常量。

        /// <summary>
        /// 编译时常量        /// </summary>
        public const int Num = 100;        /// <summary>
        /// 运行时常量        /// </summary>
        public static readonly int Year = 2017;

  3.编译时常量只能用于数字和字符串,运行时常量也是一种常量,因为在构造函数执行后它不能被再次修改。

  4.const 比 readonly 效率高,但灵活性低。

三、推荐使用 is 或 as 操作符而不是强制类型转换

  1.as 比强转更加高效、安全。

  2.as 操作符不能配合值类型使用,因为值类型永远不可能为 null。

四、使用 Conditional 特性而不是 #if 条件编译

五、为类型提供 ToString() 方法

  1.应该为类型提供一个合适的 ToString() 版本,否则使用者会根据类的一些属性来自行构造并用于显示。

  2.object 默认提供的 ToString() 方法会返回类型的完整名称,意义不大。如:System.Drawing.Rect。

  3.重写所有类型的 ToString(),可以简单明了的显示对象的摘要信息。

六、理解几个等同性判断之间的关系

  1.系统提供 4 种函数判断两个对象是否“相等”。

  2.对于前两种方法,我们永远不要重新定义,我们通常要重写 Equals 方法。

  3.重写 Equals 的类型也要实现 IEquatable<T>,如果是结构体的话需要实现 IStructuralEquatable。

  4.引用同一个 DataRow,会认为相等,如果想比较内容的话,而不是引用地址,那么就应该重写 Equals() 实例方法。

  5.Equals() 实例方法的重写原则:对于所有的值类型,都应该重写 Equals() 方法,对于引用类型,如果不能满足需要时才去重写该方法。重写该方法的同时也需要重写 GetHashCode() 方法。

  6.operator == ():只要创建的是值类型,都必须重新定义 operator == (),因为系统默认是通过反射来比较两个值是否相等,效率过低。

七、理解 GetHashCode() 的陷阱

  1.对于我们实现的大多数类型来说,避免实现 GetHashCode()。

  2.GetHashCode() 的重载版本必须遵循以下三条原则:

  (1)如果两个对象相等(由 operator == 定义),那么它们必须生成相同的散列码。

  (2)对于任何一个对象 A,A.GetHashCode() 必须保持不变。

  (3)对于所有的输入,散列函数应该在所有整数中按照随机分布生成散列码。

八、推荐使用查询语法而不是循环

  示例:

            //1.使用循环
            var foo = new int[100];            for (int i = 0; i < 100; i++)
            {
                foo[i] = i * i;
            }            //使用查询语法
            var foo2 = (from n in Enumerable.Range(0, 100) select n * n).ToArray();

  1.有些方法语法没有对应的查询语法,如 Take、TaskWhile、Skip、SkipWhile、Min、Max 等,就需要使用方法语法。

九、避免在 API 中使用转换操作符

十、使用可选参数减少方法重载的数量

  1.对于程序集的第一次发布,可以随意使用可选参数和命名参数。而在进行后续发布时,必须为额外的参数创建重载。这样才能保证现在的程序仍能正常运行。此外,在任何的后续发布中,都要避免修改参数的名称,因为参数名称已经成为公有接口的一部分。

十一、理解短小方法的优势

  1.我们最好尽可能地编写出最清晰的代码,将优化工作交给 JIT 完成。一个常见的错误优化是,我们将大量的逻辑放在一个函数中,以为这样可以减少额外的方法调用开销。

        public string Test(bool isTrue)
        {            var sb = new StringBuilder();            if (isTrue)
            {
                sb.AppendLine("A");
                sb.AppendLine("B");
                sb.AppendLine("C");
            }            else
            {
                sb.AppendLine("E");
                sb.AppendLine("F");
                sb.AppendLine("G");
            }            return sb.ToString();
        }

  在第一次调用 Test 方法时, if-else 的两个分支都被 JIT 编译,而实际上只需要编译其中一个,修改后:

        public string Test2(bool isTrue)
        {            var sb = new StringBuilder();            if (isTrue)
            {                return Method1();
            }            else
            {                return Method2();
            }
        }

  现在进行了方法拆分,这两个方法就可以根据需要进行 JIT 编译,而不必第一次进行全部编译。

  2.可以将 if-else 分支中有超过几十条的语句,或者某个分支专门用来处理程序发生的错误,或者 switch 语句中的每个 case 中的代码进行选择性的提取。

  3.短小精悍的方法(一般包含较少的局部变量)会让 JIT 更容易地进行寄存器选择工作,即选择哪些局部变量放在寄存器中,而不是栈上。

  4.尽量编写短小精悍的方法。

时间: 2024-10-10 23:16:48

C# 语言习惯的相关文章

改善 C# 的语言习惯(一) - 使用属性而不是可访问的数据成员(整理中)

改善 C# 的语言习惯(一) - 使用属性而不是可访问的数据成员 序 为什么我们的程序运行得棒棒的,还要改呢?Why? 答:我们要让程序运行得更快,执行的效率更高,代码的可读性更强,维护的成本更低... .... 我们知道,守旧主义并不适用于计算机行业. 在这里,我会告诉你已经弃用或者应该弃用的东西,并告诉你推荐的用法,以及弃用的原因和推荐使用的原因.

[.NET] 《C# 高效编程》(一) - C# 语言习惯

C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Conditional 特性而不是 #if 条件编译 五.为类型提供 ToString() 方法 六.理解几个等同性判断之间的关系 七.理解 GetHashCode() 的陷阱 八.推荐使用查询语法而不是循环 九.避免在 API 中使用转换操作符 十.使用可选参数减少方法重载的数量 十一.理解短小方法的优

《Effective C#》快速笔记(一)- C# 语言习惯

目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Conditional 特性而不是 #if 条件编译 五.为类型提供 ToString() 方法 六.理解几个等同性判断之间的关系 七.理解 GetHashCode() 的陷阱 八.推荐使用查询语法而不是循环 九.避免在 API 中使用转换操作符 十.使用可选参数减少方法重载的数量 十一.理解短小方法的优势 一.使用属性

语言创新在当代文学教育中的具体使用

一.当代文学教育的困境 1.文学教育的影响力降低 当代文学的发展进程中,受到了科学技术等方面的冲击,在社会上的影响力大不如前,在学校教育中,对学生的吸引力也不如从前了. 市场需求的变化,就业压力的不断加剧,汉语言文学专业也不得不顺应变化而调整为广告文案.新闻传播.语言教育等方面的实用性教育模式,以满足学生就业需要,导致了传统性质上的文学教育有所变化. 与此同时,在大众文化的氛围下,文学审美受到销蚀,更加倾向于娱乐化,青少年中所流行的网络文学对经典文学构成了强有力的挑战.在双重影响下,文学教育本身

GO 语言周报【七月第 1 期】

TIOBE 七月排名 Go 进入前十 TIOBE 七月头条:Go 语言达到历史最高并进入前十.对于 Go 语言来说,这是一个里程碑时刻,我们可以更大胆地想象,它下一步的发展会达到怎样的高度.Go 是否能够真正成为编程语言中的重量级角色,甚至在未来将JavaScript 和 Python 甩在身后?Kotlin.Elixir和Hack 这些新兴语言本月排名并未上升,Kotlin 下降了 5 位,Hack下降了 6 位 而 Elixir 下降了 5 位并且掉出了前五十. Erlang 和 Go 的对

Linux字符集和系统语言设置-LANG,locale,LC_ALL,POSIX等命令及参数详解

博文说明[前言]: 本文将通过个人口吻介绍Linux字符集和系统语言设置,包括LANG,locale,LC_ALL,POSIX等命令及参数详解的相关知识,在目前时间点[2017年6月21号]下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指出问题共同交流,在后续工作及学习中如发现本文内容与实际情况有所偏差,将会完善该博文内容. 本文参考文献引用链接: 1.http://blog.csdn.net/z4213489/article/details/7937894[好文,必看]

C 语言的第 02 课:C 语言的开发环境

工欲善其事,必先利其器.不知道还是不是记得上一篇文章中说到的,计算机本身是一个数据输入及输出的设备.所以,为了将你大脑中的各种 idea 输入到电脑,且最终生成能够执行的程序,总是要预备点什么的. 通常来说,C 语言系统应该由 3 个部分构成,分别是:程序的开发环境.C 语言和 C 语言的库. 程序的开发环境 计算机本身是一个数据的输入及输出的设备.编程这一动作,同样是一个数据的输入及输出的设备.通常是输入一些字母,然后生成可以被计算机解释的“exe”文件.所以需要一个能够允许输入的软件(文本编

android 语言定制

本文是主要对android定制多语言的问题进行深入研究后,总结了其定制的机制和其具体实现方法.如果想深入了解其定制的机制,可阅读本文第一部分,如果只想了解如何定制,请参考第二部分. 第一部分 多语言定制的机制 1.ICU4C简介 ICU4C(ICU for C, http://site.icu-project.org/ ) 是ICU在C/C++平台下的版本, ICU(International Component for Unicode)是基于"IBM公共许可证"的,与开源组织合作研究

快速学习C语言途径,让你少走弯路

1.标准C语言能干什么? 坦白讲,在今天软件已经发展了半个多世纪,单纯的C语言什么都干不了.标准C语言库只提供了一些通用的逻辑运算方法以及字符串处理,当然字符串在C语言看来也是一种操作内存的方法,所以单纯的C什么都做不了,不论是游戏客户端,服务器以及其他插件标准C语言要配合相应的系统C调用和其他语言共同完成一个完整的软件.所以C只是一个入门,要想吃软件这碗饭还有很长的路要走 2.从学会C语言到能写软件还要做什么? I.个人认为第一步是学习数据结构和算法.推荐一本书:<数据结构(C语言版) >