以后的学习地址
摘要:http://www.cnblogs.com/wing011203/tag/Effective/
阅读全文
posted @
2012-10-25 11:23
Q&A
阅读(119)
推荐(0)
21.使用委托表达回调
摘要:回调用于为服务器和客户端之间提供异步的反馈,其中可能会涉及到多线程或者需要提供一个入口点用于同步更新,在C#中,我们使用委托来表达回调。委托为我们提供了类型安全的回调定义,虽然大多数常见的委托应用都和事件相关,但是那并不是委托应用的全部场合。当类之间有通信的需要,并且我们期望一种比接口更加松耦合的机制时,委托就是最合适的选择。委托允许我们在运行时配置目标,并且可以通知多个对象,委托对象中包含一个方法引用,这个方法可以是静态方法,也可以是实例方法。我们还可以为委托绑定多个方法,利用委托的多播机制,可以一次调用多个方法。但是有两点需要注意:1)如果有委托调用出现异常,那么这种构造将不能保证安全;2
阅读全文
posted @
2012-10-25 11:22
Q&A
阅读(231)
推荐(0)
20.明白接口实现和虚函数实现的区别
摘要:接口实现没有多态功能, 以接口调用接口方法,其性质表现为实现接口的类的方法行为。若要让接口实现多态功能,需要用virtual 实现。如下:public interface IA { void Print(); } public class MyClass:IA { public virtual void Print() { Console.WriteLine("MyClass"); } } public class MyDerive : MyClass { public override void Print() { Console.WriteLine("MyDe
阅读全文
posted @
2012-10-25 10:51
Q&A
阅读(217)
推荐(0)
19.选择定义和实现接口,而不是继承
摘要:基类可以用来描述和实现一些具体的相关类型 的行为。接口则是描述一些原子级别的功能块,不相关的具 体类型都可以实现它 。接口 以功能块的方法来描述这些对象 的行为。如果你明白它们的不同之处,你就可 以创建出表达力更强的设计,并且它们面对修改是有很加强的伸缩性 的。类 的继承可以用来定义一些相关 类型 。通过实现一些接口来暴露部份功能来访 问这些类型接口还可以防止被装箱的struct的拆箱问题。
阅读全文
posted @
2012-10-25 10:31
Q&A
阅读(222)
推荐(0)
18.实现标准的Dispose模式
摘要:首先来看MSDN中关于这个接口的说明:[ComVisible(true)]public interface IDisposable{ // Methodsvoid Dispose();}1.[ComVisible(true)]:指示该托管类型对 COM 是可见的.2.此接口的主要用途是释放非托管资源。当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。但无法预测进行垃圾回收的时间。另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。将此接口的Dispose方法与垃圾回收器一起使用来显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。一:基本应用1.我们来定义
阅读全文
posted @
2012-10-25 10:02
Q&A
阅读(281)
推荐(0)
17. 装箱、拆箱的最小化
摘要:是的,值类型可以转化为System.Object或者其它任何的接 口引用。这些转化是隐式的,使得发现它们成为繁杂的工作。这些也就是环境和语言的规则,装箱与拆箱 操作会在你不经意时做一些对象 的拷贝,这会产生一些BUG 。同样,把值类型多样化处理会对性能有所损 失。时刻注意那些把值类型转化成System.Object或者接口类型 的地方:把值类型放到集合里,调用定义参 数为System.Object类型 的方法,或者强制转化为System.Object。能够避免就尽量避免
阅读全文
posted @
2012-10-25 09:24
Q&A
阅读(163)
推荐(0)
16.垃圾最小化
摘要:垃圾回收器在管理应用程序的内存上确实很高效。但请记住,创建和释放堆对象还是很 占时间的。避免创 建大量的对象,也不要创建你不使用的对象 。也要避免在局部函数上多次创建引用对象 。相反,把局部变 量提供为类型成员变量,或者把你最常用的对象实例创建为静态对象 。最后,考虑使用可变对象创建器来 构造恒定对象
阅读全文
posted @
2012-10-24 09:33
Q&A
阅读(183)
推荐(0)
15.使用using和try/finally来做资源清理
摘要:只有是实现了IDispose接口的类型的调用都应使用using 或者try/finally释放对象。
阅读全文
posted @
2012-10-24 09:23
Q&A
阅读(125)
推荐(0)
14.使用构造函数链
摘要:这是C#里的最后一个关于对象构造的原则,是时候复习一下,一个类型在构造时的整个事件顺序了。你须 要同时 明白一个对象 的操作顺序和默认的预置方法的顺序。你构造过程中,你应该努力使所有的成员变量 只精确的初始化一次。最好的完成这个 目标的方法就是尽快的完成变量的初始化 。这是某个类型第一次构 造一个实例时的顺序: 1、静态变量存储位置0 。 2 、静态变量预置方法执行 。 3、基类 的静态构造函数执行 。 4 、静态构造函数执行 。 5、实例变量存储位置0 。 6、实例变量预置方法执行 。7、恰当 的基类实例构造函数执行 。 8、实例构造函数执行 。 后续的同样类型的实例从...
阅读全文
posted @
2012-10-24 09:11
Q&A
阅读(283)
推荐(0)
12.选择变量初始化而不是赋值
摘要:这个我保留意见,我觉得有点时候用构造函数更好。
阅读全文
posted @
2012-10-23 20:49
Q&A
阅读(127)
推荐(0)
理解GC机制
摘要:对于文件句柄,数据库链接,GDI+等非托管资源,建议实现IDisposeable接口。
阅读全文
posted @
2012-10-23 20:36
Q&A
阅读(167)
推荐(0)
11.选择foreach循环
摘要:foreach是一个应用广泛的语句 。它为数组的上下限 自成正确的代码,迭代多维数组,强制转化为恰当 的类 型 使用最有效的结构 ,还有,这是最重要的,生成最有效的循环结构。这是迭代集合最有效的方法。这 ( ) 样,你写出的代码更持久 译注 :就是不会因为错误而改动太多的代码 ,第一次写代码的时候更简洁。这 ( ) 对生产力是一个小的进步,随着时间的推移会累加起来
阅读全文
posted @
2012-10-23 20:00
Q&A
阅读(165)
推荐(0)
10.了解GetHashCode()
摘要:1、对于引用类型,GetHashCode()函数返回当前对象的ID。(对象的ID在对象创建时自动分配)2、对于值类型,GetHashCode()返回类型的第一个字段的散列值。 public struct MyStruct { private string _msg; private int _id; private DateTime _epoch; } 从MyStruct 对象上返回的散列值是从该对象的_msg 成员上生成的。下面的代码片断总是返回trueMyStruct s = new MyStruct( ); return s.GetHashCode( ) == s._msg...
阅读全文
posted @
2012-10-23 19:50
Q&A
阅读(198)
推荐(0)
9.了解四个相等判断的用法
摘要:Object.ReferenceEquals(Object left,Object right) :判断两个对象的ID是否相同。Object .Equals(Object left,Object right):当不知道两个对象的类型时判断这两个对象是否相同,它是原理是基于“==”和第一个对象的Equals()。实例的Equals(Object right)方法: 原则是不管什么时候,在创建一个值类型时重载Equals()方法,并且你不想让引用类型遵从默认引用类型 的 语义时也重载Equals(),就像System.Object定义的那样 。当你写你 自己的Equals() 时,遵从要点里实现.
阅读全文
posted @
2012-10-23 15:44
Q&A
阅读(167)
推荐(0)
5.重写ToString()方法。
摘要:.NET Framework提供给我们拓展其内置格式化字符串接口:IFormattable 、ICustomFormatter 、IFormatProvider本文介绍两个自定义格式字符串的方法:1、在继承IFormattable接口的自定义类型中实现IFormattable接口的ToString方法2、在继承ICustomFormatter 和 IFormatProvider 接口的自定义类型中实现 IFormatProvider 接口的GetFormat方法和ICustomFormatter 接口的Format方法。测试方法:1、根据方法1和方法2 分别创建两个自定义类:class CUn
阅读全文
posted @
2012-10-22 15:33
Q&A
阅读(329)
推荐(0)
4.用条件属性而不是#if
摘要:时以or 的形式并列的。例如,下面这个版本的CheckState会在DEBUG或者TRACE为真时被调用: [ Conditional( "DEBUG" ), Conditional( "TRACE" ) ] private void CheckState( ) 如果要产生一个and 的并列条件属性,你就要 自己事先直接在代码里使用预处理命令定义一个标记: #if ( VAR1 && VAR2 ) #define BOTH #endif
阅读全文
posted @
2012-10-22 14:32
Q&A
阅读(132)
推荐(0)
3.选择is或者as操作符而不是做强制类型转换
摘要:强制类型转换: 只考虑转换编译时类型与目标类型是否可以转换;若类有定义自己的转换运算符,则会调用转换函数。as: 若类有定义自己的转换运算符,不会调用转换函数。建议使用as 做为转换函数。is: 只做判断,不做转换。所以建议用法: as 用于自定义类型的转换,强制转换用于内置类型转换(当自定义内型有转换函数时,也要用强制转换)。GetType()用于精确类型判断。
阅读全文
posted @
2012-10-22 14:00
Q&A
阅读(123)
推荐(0)
2.为你的常量选择readonly而不是const
摘要:const 在编译时需要确定其值,所以const的字段默认是静态的,因而不能这样声明:static const string str; 因为const 是编译时确定,所以其不能用于带new的类型,只能用于一些简单类型。注const DateTime dt=new DateTime();是错误的。readonly 是运行时常量,其值在编译时不确定。
阅读全文
posted @
2012-10-22 09:17
Q&A
阅读(120)
推荐(0)
1.尽可能的使用属性,而不是数据成员
摘要:综上所述,只要打算将数据暴露在类型 的公有接口或者受保护接口中,我们都应该使用属性来实现。对于 具有序列或者字典特征的类型 ,则应该采用索引器。所有的数据成员都应一律声明为私有。
阅读全文
posted @
2012-10-22 09:00
Q&A
阅读(120)
推荐(0)