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

C# 语言习惯

目录

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

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

二、使用运行时常量(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.尽量编写短小精悍的方法。



【博主】反骨仔

【原文】http://www.cnblogs.com/liqingwen/p/6754401.html

【参考】《C# 高效编程》

时间: 2024-10-13 17:12:09

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

C语言高效编程的几招,你会了几招了?

编写高效简洁的C 语言代码,是许多软件工程师追求的目标.本文就工作中的一些体会和经验做相关的阐述,不对的地方请各位指教. 第1 招:以空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题,我们就有了解决问题的第1 招--以空间换时间. 例如:字符串的赋值. 方法A,通常的办法: #define LEN 32 char string1 [LEN]; memset (string1,0,LEN); strcpy (string1,"This is a

C语言高效编程的几招(绝对实用,绝对经典)

编写高效简洁的C语言代码,是许多软件工程师追求的目标.废话不说,走起! 第一招:以空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题 eg.字符串的赋值 //方法A 通常办法 #define LEN 32 char string1[LEN]; memset(string1,0,LEN); strcpy(string1,"This is an example!!"); //方法B const char string2[LEN]=&quo

编程有哪些语言

编程有哪些语言?各有什么特点? 编程语言 C,C++,JAVA,VB,VC,FoxPro,Delphi,SQL,PHP,ASP,JSP等. 下为引用,介绍的很详细了. 计算机语言的种类非常的多,总的来说可以分成机器语言,汇编语言,高级语言三大类. 电脑每做的一次动作,一个步骤,都是按照以经用计算机语言编好的程序来执行的,程序是计算机要执行的指令的集合,而程序全部都是用我们所掌握的语言来编写的.所以人们要控制计算机一定要通过计算机语言向计算机发出命令. 计算机所能识别的语言只有机器语言,即由0和1

[.NET] 《Effective C#》快速笔记 - C# 高效编程要点补充

<Effective C#>快速笔记 - C# 高效编程要点补充 目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是这一系列的最后一篇. 四十五.尽量减少装箱拆箱 值类型是数据的容器,不支持多态. 装箱把一个值类型放在一个未确定类型的引用对象中,让该值作为引用类型所使用.拆箱指从引用类型的位置取出值的一个副本. 装箱拆箱都是比较影响性能的手段,应

我的高效编程秘诀

高效编程.高效学习.高效工作.高效生活 高效的意思是指在相同或更短的时间里完毕比其她人很多其它的任务,并且质量与其她人一样或者更好.用英文来说就是write less.do more.这是程序永远的主题,在我们日常编程中一段代码常常复用的时候我们会进行代码封装,借助一些工具来高速定位错误这些都有利于提高我们编程的效率.今天和小伙伴们聊聊高效编程的秘诀,事实上不仅仅是高效编程的秘诀,更是高效学习.生活和工作的秘诀,由于小编感觉编程就如同人生一样,一样的丰富多彩,一样的璀璨夺目.指导小编高效编程.生

《Effective C#》快速笔记 - C# 高效编程要点补充

目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是该系列的最后一篇.也许有些理论有可能会过时,我想它仍有存在的必要,人的知识水平也是一个不断成长的过程,学会站在前人的肩膀上,尝试不断的借鉴与总结. 四十五.尽量减少装箱拆箱 值类型是数据的容器,不支持多态. 装箱把一个值类型放在一个未确定类型的引用对象中,让该值作为引用类型所使用.拆箱指从引用类型的

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

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

shell脚本编程的一些好习惯

shell脚本编程的一些好习惯 1.命名规则 脚本命名以.sh结尾,名称尽量见名之意.以下是几种可供参考的脚本命名风格.通过以下清新脱俗的风格,读者能够很easy的明白脚本的作用.         clearlog.sh          ClearLog.sh          clearSql.sh         snmp_install.sh         Monitor.sh 2.脚本信息 为脚本加入生动的信息,比如脚本功能的描述,作者,时间,版本信息等.     #!/bin/ba

【转载】架构师速成-如何高效编程

引子 赵云大喝一声,挺枪骤马杀入重围,左冲右突,如入无人之境.那枪浑身上下,若舞梨花:遍体纷纷,如飘瑞雪. 赵云是所有历史人物中我最喜欢的一个,如果放到现代,他走了it的道路,一定可以成为一个编程高手.为什么? 其实古时打仗也是一门技术活,需要有勇有谋,跟it没有什么太大的区别.打仗要修身.修技.修器才能左冲右突,如入无人之境,同样做it也要修身.修技.修器,才能高效编程,如入无人之境. 高效编程的修炼 何谓修身.修技.修器? 修身,古今都是修炼自己的体魄和思维,使自己体魄强健,思维敏捷 修技,