我的编程空间,编程开发者的网络收藏夹
学习永远不晚

关于C#程序优化的五十种方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

关于C#程序优化的五十种方法

一、用属性代替可访问的字段
1、.NET数据绑定只支持数据绑定,使用属性可以获得数据绑定的好处;
2、在属性的get和set访问器重可使用lock添加多线程的支持。   

二、readonly(运行时常量)和const(编译时常量)
1、const只可用于基元类型、枚举、字符串,而readonly则可以是任何的类型;
2、const在编译时将替换成具体的常量,这样如果在引用中同时使用了const和readonly两种值,则对readonly的再次改变将会改变设计的初衷,这是需要重新编译所更改的程序集,以重新引用新的常量值。
3、const比readonly效率高,但失去了应用的灵活性。   

三、is与as
1、两者都是在运行时进行类型的转换,as操作符只能使用在引用类型,而is可以使用值和引用类型;
2、通常的做法是用is判断类型,然后选择使用as或强类型转换操作符(用operater定义的转换)有选择地进行。   

四、ConditionalAttribute代替#if #endif条件编译
1、ConditionalAttribute只用于方法级,对其他的如类型、属性等的添加都是无效的;而#if #endif则不受此限制;
2、ConditionalAttribute可以添加多个编译条件的或(OR)操作,而#if #endif则可以添加与(AND)[这里可以完全定义为另一个单独的符号];
3、ConditioanlAttribute定义可以放在一个单独的方法中,使得程序更为灵活。   

五、提供ToString()方法
1、可以更友好的方式提供用户详细的信息;
2、使用IFormatter.ToString()方法提供更灵活的定制,如果添加IFormatProvider 和ICustomFormatter接口则更有意义的定制消息输出。   

六、值和引用类型的区别
1、值类型不支持多态,适合存储应用程序操作的数据,而引用则支持多态,适用于定义应用程序的行为;
2、对于数组定义为值类型可以显著提高程序的性能;
3、值类型具有较少的堆内存碎片、内存垃圾和间接访问时间,其在方法中的返回是以复制的方式进行,避免暴露内部结构到外界;
4、值类型应用在如下的场景中:类型的职责主要是用于数据存储;公共接口完全由一些数据成员存取属性定义;永远没有子类;永远没有多态行为。   

七、值类型尽可能实现为常量性和原子性的类型
1、使我们的代码更易于编写和维护;
2、初始化常量的三种策略:在构造中;工厂方法;构造一个可变的辅助类(如StringBuilder)。   

八、确保0为值得有效状态
1、值类型的默认状态应为0;
2、枚举类型的0不应为无效的状态;在FlagsAttribute是应确保0值为有效地状态;
3、在字符串为为空时可以返回一个string.Empty的空字符串。   

九、相等判断的多种表示关系
1、ReferenceEquals()判断引用相等,需要两个是引用同一个对象时方可返回true;
2、静态的Equals()方法先进行引用判断,再进行值类型判断的;
3、对于引用类型的判断可以在使用值语义时使用重写Equals()方法;
4、重写Equals()方法时也应当重写GetHashCode()方法,同时提供operater==()操作。   

十、理解GetHashCode()方法的缺陷
1、GetHashCode()仅应用在基于散列的**定义键的散列值,如HashTable或Dictionary;
2、GetHashCode()应当遵循相应的三条规则:两个相等对象应当返回相同的散列码;应当是一个实例不变式;散列函数应该在所有的整数中产生一个随机的分布。   

十一、优先使用foreach循环语句
1、foreach可以消除编译器对for循环对数组边界的检查;
2、foreach的循环变量是只读的,且存在一个显式的转换,在**对象的对象类型不正确时抛出异常;
3、foreach使用的**需要有:具备公有的GetEnumberator()方法;显式实现了IEnumberable接口;实现了IEnumerator接口;
4、foreach可以带来资源管理的好处,因为如果编译器可以确定IDisposable接口时,可以使用优化的try…finally块;   

十二、默认字段的初始化优于赋值语句
1、字段生命默认会将值类型初始化为0,引用类型初始化为null;
2、对同一个对象进行多次初始化会降低代码的执行效率;
3、将字段的初始化放到构造器中有利于进行异常处理。   

十三、使用静态构造器初始化静态成员
1、静态构造器会在一个类的任何方法、变量或者属性访问之前执行;
2、静态字段同样会在静态构造器之前运行,同时静态构造器有利于异常处理。   

十四、利用构造器链(在.NET 4.0已经用可选参数解决了这个问题)
1、用this将初始化工作交给另一个构造器,用base调用基类的构造器;
2、类型实例的操作顺序是:将所有的静态字段都设置为0;执行静态字段初始化器;执行基类的静态构造器;执行当前类型的静态构造器;
将所有的实例字段设置为0;执行实例字段初始化器;执行合适的基类实例构造器;执行当前类型的实例构造器。   

十五、利用using和try/finally语句来清理资源
在IDisposable接口的Dispose()方法中用GC.SuppressFinalize()可通知垃圾收集器不再执行终结操作。   

十六、尽量减少内存垃圾
1、分配和销毁一个堆上的对象都要花费额外的处理器时间;
2、减少分配对象数量的技巧:经常使用的局部变量提升为字段;提供一个类,用于存储Singleton对象来表达特定类型的常用实例。
3、用StringBuilder进行复杂的字符串操作。   

十七、尽量减少装箱和拆箱
1、关注一个类型到System.Object的隐式转换,同时值类型不应该被替换为System.Object类型;
2、使用接口而不是使用类型可以避免装箱,即将值类型从接口实现,然后通过接口调用成员。   

十八、实现标准Dispose模式
1、使用非内存资源,它必须有一个终结器,垃圾收集器在完成没有终结其的内存对象后,会将实现了终结器对象的添加到终结队列中,然后垃圾收集器会启动一个新的线程来运行这些对象上的终结器,这种防御性的变成方式是因为如果用户忘记了调用Dispose()方法,垃圾回收器总是会调用终结器方法的,这样可以避免出现非托管的内存资源不被释放引起内存泄漏的问题;
2、使用IDisposable.Dispose()方法需要做四个方面的工作:释放所有的非托管资源;释放所有的托管资源;设置一个状态标记来表示是否已经执行了Dispose();调用GC.SuppressFinalize(this)取消对象的终结操作;
3、为需要多态的类型添加一个受保护的虚方法Dispose(),派生类通过重写这个方法来释放自己的任务;
4、在需要IDisoposable接口的类型中,即使我们不需要一个终结器也应该实现一个终结器。   

十九、定义并实现接口优于继承类型
1、不相关的类型可以共同实现一个共同的接口,而且实现接口比继承更容易;
2、接口比较稳定,他将一组功能封装在一个接口中,作为其他类型的实现合同,而基类则可以随着时间的推移进行扩展。   

二十、明辨接口实现和虚方法重写
1、在基类中实现一个接口时,派生类需要使用new来隐藏对基类方法的使用;
2、可以将基类接口的方法申明为虚方法,然后再派生类中实现。   

二十一、使用委托表达回调
1、委托对象本身不提供任何异常捕获,所以任何的多播委托调用都会结束整个调用链;
2、通过显示调用委托链上的每个委托目标可以避免多播委托仅返回最后一个委托的输出。   

二十二、使用事件定义外部接口
1、应当声明为共有的事件,让编译器为我们创建add和renmove方法;
2、使用System.ComponentModel.EventHandlerList容器来存储各个事件处理器,在类型中包含大量事件时可以使用他来隐藏所有事件的复杂性。   

二十三、避免返回内部类对象的引用
1、由于值类型对象的访问会创建一个该对象的副本,所以定义一个值类型的的属性完全不会改变类型对象内部的状态;
2、常量类型可以避免改变对象的状态;
3、定义接口将访问限制在一个子集中从而最小化对对象内部状态的破坏;
4、定义一个包装器对象来限制另一个对象的访问;
5、希望客户代码更改内部数据元素时可以实现Observer模式,以使对象可以对更改进行校验或相应。   

二十四、声明式编程优于命令式编程
可以避免在多个类似的手工编写的算法中犯错误的可能性,并提供清晰和可读的代码。   

二十五、尽可能将类型实现为可序列化的类型
1、类型表示的不是UI控件、窗口或者表单,都应使类型支持序列化;
2、在添加了NonSerializedAttribute的反序列化的属性时可以通过实现IDeserializationCallback的OnDeserialization()方法装入默认值;
3、在版本控制中可以使用ISerializable接口来进行灵活的控制,同时提供一个序列化的构造器来根据流中的数据初始化对象,在实现时还要求SerializationFormatter异常的许可;
4、如果需要创建派生类则需要提供一个挂钩方法供派生类使用。   

二十六、使用IComparable和IComparer接口实现排序关系
1、IComparable接口用于为类型实现最自然的排序关系,重载四个比较操作符,可以提供一个重载版的CompareTo()方法,让其接受具体类型作为参数;
2、IComparer用于提供有别于IComparable的排序关系,或者为我们提供类型本身说没有实现的排序关系。   

二十七、避免ICloneable接口
1、对于值类型永远不需要支持ICloneable接口,使用默认的赋值操作即可;
2、对于可能需要支持ICloneable接口的基类,应该为其创造一个受保护的复制构造器,并应当避免支持IConeable接口。   

二十八、避免强制转换操作符
通过使用构造器来代替转换操作符可以使转换工作变得更清晰,由于在转换后使用的临时对象,容易导致一些诡异的BUG。   

二十九、只有当新版积累导致问题时才考虑使用new修饰符   

三十、尽可能实现CLS兼容的程序集
1、创建一个兼容的程序集需要遵循两条规则:程序集中所有公有和受保护成员所使用的参数和返回值类型都必须与CLS兼容;任何与CLS不兼容的公有和受保护成员都必须有一个与CLS兼容的替代品;
2、可以通过显式实现接口来避开CLS兼容类型检查,及CLSCompliantAttribute不会检查私有的成员的CLS兼容性。   

三十一、尽可能实现短小简洁的方法
1、JIT编译器以方法为单位进行编译,没有被调用的方法不会被JIT编译;
2、如果将较长的Switch中的Case语句的代码替换成一个一个的方法,则JIT编译器所节省的时间将成倍增加;
3、短小精悍的方法并选择较少的局部变量可以获得优化的寄存器使用;
4、方法内的控制分支越少,JIT编译器越容易将变量放入寄存器。   

三十二、尽可能实现小尺寸、高内聚的程序集
1、将所有的公有类以及共用的基类放到一些程序集中,把为公有类提供功能的工具类也放入同样的程序集中,把相关的公有接口打包到他们自己的程序集中,最后处理遍布应用程序中水平位置的类;
2、原则上创建两种组件:一种为小而聚合、具有某项特定功能的程序集,另一种为大而宽、包含共用功能的程序集。   

三十三、限制类型的可见性
1、使用接口来暴露类型的功能,可以使我们更方便地创建内部类,同时又不会限制他们在程序集外的可用性;
2、向外暴露的公有类型越少,未来扩展和更改实现所拥有的选择就越多。   

三十四、创建大粒度的Web API
这是在机器之间的交易的频率和载荷都降到最低,将大的操作和细粒度的执行放到服务器执行。   

三十五、重写优于事件处理器
1、一个事件处理器抛出异常,则事件链上的其他处理器将不会被调用,而重写的虚方法则不会出现这种情况;
2、重写要比关联事件处理器高效得多,事件处理器需要迭代整个请求列表,这样占用了更多的CPU时间;
3、事件能在运行时响应,具有更多的灵活性,可以对同一个事件关联多个响应;
4、通行的规则是处理一个派生类的事件是,重写方式较好。   

三十六、合理使用.NET运行时诊断
1、System.Diagnostics.Debug\Trace\EventLog为运行时提供了程序添加诊断信息所需要的所有工具,EventLog提供入口时的应用程序能写到系统事件日志中;
2、最后不要写自己的诊断库,.NET FCL 已经拥有了我们需要的核心库。   

三十七、使用标准配置机制
1、.NET框架的System.Windows.Application类为我们定义了建立通用配置路径的属性;
2、Application.LocalAppDataPath 和 Application.userDataPath 会生成本地数据目录和用户数据的路径名;
3、不要在ProgramFiles和Windows系统目录中写入数据,这些位置需要更高的安全权限,不要指望用户拥有写入的权限。   

三十八、定制和支持数据绑定
1、BindingMananger和CurrencyManager这两个对象实现了控件和数据源之间的数据传输;
2、数据绑定的优势:使用数据绑定要比编写自己的代码简单得多;应该将它用于文本数据项之外的范围 —— 其他显示属性也可以被绑定;对于 Windowos Forms 数据绑定能够处理多个控件同步的检查相关数据源;
3、在对象不支持所需的属性时,可以通过屏蔽当前的对象,然后添加一个想要的对象来支持数据绑定。   

三十九、使用.NET验证
1、ASP.NET中有五种控件来验证有效性,可以用CustomValidator派生一个新类来增加自己的认证器;
2、Windows验证需要子System.Windows.Forms.Control.Validating写一个事件处理器。   

四十、根据需要选用恰当的**
1、数组有两个比较明显的缺陷:不能动态的调整大小;调整大小非常耗时;
2、ArrayList混合了一维数组和链表的特征,Queue和Stack是建立在Array基础上的特殊数组;
3、当程序更加灵活的添加和删除项时,可以使更加健壮的**类型,当创建一个模拟**的类时,应当为其实现索引器和IEnumberable接口。   

四十一、DataSet优于自定义结构
1、DataSet有两个缺点个:使用XML序列化机制的DataSet与非.NET 代码之间的交互不是很好;DataSet是一个非常通用的容器;
2、强类型的DataSet打破了更多的设计规则,其获得的开发效率要远远高于自己编写的看上去更为优雅的设计。   

四十二、利用特性简化反射
通过设计和实现特性类,强制开发人员用他们来声明可被动态使用的类型、方法和属性,可以减少应用程序的运行时错误,提高软件的用户满意度。   

四十三、避免过度使用反射
1、Invoke成员使用的参数和返回值都是System.Object,在运行时进行类型的转换,但出现问题的可能性也变得更多了;
2、接口使我们可以得到一个更为清晰、也更具可维护性的系统,反射是一个很强大的晚期绑定机制,.NET框架使用它来实现Windows控件和Web控件的数据绑定。   

四十四、为应用程序创建特定的异常类
1、需要不同的异常类的唯一原因是让用户在编写catch处理器时能够方便地对不同的错误采取不同的做法;
2、可能有不同的修复行为时,我们才应该创建多种不同的异常类,通过提供异常基类所支持的所有构造器,可以为应用程序创建功能完整的异常类,使用InnerException属性可以保存更低级别错误条件所产生的所有错误信息。   

四十五、优先选择异常安全保证
1、强异常保证在从异常中恢复和简化异常处理之间提供了最好的平衡,在操作因为异常而中断,程序的状态保留不变;
2、对将要修改的数据做防御性的复制,对这些数据的防御性复制进行修改,这中间的操作可能会引发异常,将临时的副本和原对象进行交换;
3、终结器、Dispose()方法和委托对象所绑定的目标方法在任何情况下都应当确保他们不会抛出异常。   

四十六、最小化互操作
1、互操作有三个方面的代价:数据在托管堆和非托管堆之间的列举成本,托管代码和非托管代码之间切换的成本,对开发人员来说与混合环境打交道的开发工作;
2、在interop中使用blittable类型可以有效地在托管和非托管环境中来回复制,而不受对象内部结构的影响;
3、使用In/Out特性来确保最贴切的不必要的多次复制,通过声明数据如何被列举来提高性能;
4、使用COM Interop用最简单的方式实现和COM组件的互操作,使用P/Invoke调用Win32 API,或者使用C++编译器的/CLR开关来混合托管和非托管的代码;   

四十七、优先选择安全代码
1、尽可能的避免访问非托管内存,隔离存储不能防止来自托管代码和受信用户的访问;
2、程序集在Web上运行时可以考虑使用隔离存储,当某些算法确实需要更高的安全许可时,应该将那些代码隔离在一个单独的程序集中。   

四十八、掌握相关工具与资源
1、使用NUnit建立自动单元测试(集成在VS2010 中了);
2、FXCop工具会获取程序集中的IL代码,并将其与异族编码规则和最佳实践对照分析,最后报告违例情况;
3、ILDasm是一个IL反汇编工具,可以帮助我们洞察细节;
4、Shared Source CLI是一个包含.NET框架内核和C#编译器的实现源码。

四十九、为C#2.0做准备(这个规则现在已经没什么意义了,毕竟现在已经到了4.0 )
五十、了解ECMA标准

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

关于C#程序优化的五十种方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

关于C#程序优化的五十种方法

这篇文章主要介绍了C#程序优化的五十个需要注意的地方,使用c#开发的朋友可以看下
2022-11-15

win8怎样关闭程序 2种关闭win8程序的方法介绍

Win8系统是目前最新一代操作系统,也是微软公司开发的一款最具革命性变化的操作系统,主要是增加了触摸屏设备的触控体验,在操作上已经与我们熟悉的XP、Win7系统有不少改变。对于初次使用Win8系统,往往会遇到不少问题,比如不知道如何关机,不
2022-06-04

小程序redux性能优化的方法

这篇文章主要介绍“小程序redux性能优化的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“小程序redux性能优化的方法”文章能帮助大家解决问题。首先了解小程序的工作原理和性能关键点。1工作原理
2023-06-26

PHP 应用程序性能优化的关键问题和解决方法

php 应用程序性能优化的关键问题包括:慢速数据库查询:使用索引、优化查询和缓存查询结果。内存限制:使用内存分析工具、增加内存分配和优化代码。慢速网络请求:使用缓存、优化并行请求和启用 http 压缩。i/o 操作:优化文件 i/o、使用异
PHP 应用程序性能优化的关键问题和解决方法
2024-04-30

PHP转C语言:优化代码性能的关键方法

标题:PHP转C语言:优化代码性能的关键方法在软件开发中,代码性能一直是开发者们关注的重要问题之一。在Web开发领域中,PHP是一种常用的服务器端脚本语言,但其性能相对较低,特别是在处理大规模数据或高并发操作时可能导致性能瓶颈。为了提高代
PHP转C语言:优化代码性能的关键方法
2024-03-12

优化Go语言程序性能的实用方法

标题:优化Go语言程序性能的实用方法在开发Go语言程序时,性能优化是一个至关重要的环节。优化程序性能可以提高程序的运行效率,减少资源消耗,提升用户体验。本文将介绍一些优化Go语言程序性能的实用方法,通过具体的代码示例帮助读者更好地理解和应
优化Go语言程序性能的实用方法
2024-03-04

程序性能优化有哪些常见的方法?

程序性能优化方法包括:算法优化:选择时间复杂度更低的算法,减少循环和条件语句。数据结构选择:根据数据访问模式选择合适的数据结构,如查找树和哈希表。内存优化:避免创建不必要对象,释放不再使用的内存,使用内存池技术。线程优化:识别可并行化任务,
程序性能优化有哪些常见的方法?
2024-05-09

HTML 有序列表:10 种优化网站结构的创意方法

HTML 有序列表是一种广泛用于创建结构化和清晰的内容列表或序列的 HTML 元素。了解 10 种优化网站结构的有用方法,帮助您以富有创意和组织有序的方式呈现信息,让您的网站更有吸引力。
HTML 有序列表:10 种优化网站结构的创意方法
2024-02-22

怎样关闭windows8系统的Metro界面程序(2种关闭方法)

Metro界面是没有传统的"X"按钮来关闭程序,这样很多朋友就不知道如何退出程序了,好多朋友认为只能通过”任务管理器“强制结束了,其实对于X86版本win8有两个很简单的关闭方法,1.打开左侧栏--选择程序--右键-
2022-06-04

微信小程序代码包大小的优化方法

这篇文章主要讲解了“微信小程序代码包大小的优化方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“微信小程序代码包大小的优化方法”吧!setDatasetData是小程序开发中使用最频繁的接口
2023-06-26

让C程序更高效的10种方法分别是哪些

让C程序更高效的10种方法分别是哪些,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。代码之美,不仅在于为一个给定问题找到解决方案,而且还在代码的简单性、有效性、紧
2023-06-17

微信小程序调起键盘性能优化的方法

本篇内容主要讲解“微信小程序调起键盘性能优化的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序调起键盘性能优化的方法”吧!需求分析最近在项目中有一个需求,是从列表页点击评论按钮进入详
2023-06-26

快速便捷关闭win7应用程序的几种方法(图文教程)

Win7系统在稳定性和安全性上相比此前的XP和Vista已经有了很大提升,并且其多样化的智能操作带给我们更好的体验。但正是因为我们不断的安装程序,在使用久了之后,以及部分大型程序的运行中,还是会出现任务无响应的现象,这是因为某些程序自身的问
2023-05-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录