原则一: 始终用属性(Property)代替数据成员(Data Member)
1.Data Binding只支持Property,遵从Object Oriented方法;
2.更好的控制对数据的访问:
- 添加检查机制
private string _name;
public string Name
{
get{ return _name;}
set
{
if((value==null)||(value.Length==0))
{
throw new ArgumentException("Name can't be blank","Name");
}
_name=value;
}
}
- 添加多线程更方便
- Property可被定义成virtual和interface
- 给get和set方法定义不同的访问级别(e.g. set前加protected),控制类成员的可见性
- 可以使用indexer
public Address this[int index]
{
get{ return _theValue[value]; }
set{ return _theValue[value]=value;}
}
3.其他总结
- Property效率只比Data Member多一个function call,可忽略,特别是使用JIT的inline优化后
- Property同Data Member具有Code兼容性而无Binary兼容性,IL是不一样的
- Property中get和set不是类型定义、只能通过Property访问
原则二: readonly强于const
readonly | const |
---|---|
运行时常量 | 编译时常量(绝对不变) |
效率稍慢但严谨 | 效率高但容易出错 |
编译后还可以替换,只是一个变量引用 | 编译成中间代码时被替换成值类型 |
识别版本序列化 |
- private const DataTemp _dt=new DataTemp(2000,1,1);是错误,无法对一个数值进行new
原则三: 使用as或is代替强制转换
1.强制转换类型不安全,需要异常处理,来解决类型值为null的情况;而as是类型安全的,值为null的类型转换到新类型后仍然为null;
object o=Factory.GetObject();
MyType t=o as MyType;
if(o!=null)
{
//Process...
}
else
{
//report error
}
object o=Factory.GetObject();
try
{
MyType t=(MyType)o;
if(o!=null)
{
//work with t,it's MyType
}
else
{
//repoty a nullvalue exception
}
}
catch
{
//report failure
}
2.as对值类型无效无法使用;
3.is类型安全,is只对类型进行类型检测;对于null永远返回false;
if(mType is DefineType)
{
DefineType dT=(DefineType)mType;
}
原则四: 使用Conditional属性代替条件编译
1.在Debug情况下使用条件编译的代码将在发布版中消失,而使用[Conditional][attribute]则仍会编译,但不会加载到内存中;
原始代码
public string LastName
{
get
{
CheckState();
return _lastName;
}
set
{
CheckState();
_lastName = value;
CheckState();
}
}
Conditional属性使用
[Conditional("DEBUG")]
private void CheckState()
{
// same code as above
}
release版中代码
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
2.但Conditional属性无法在函数体中使用,必须使用在返回值为空的方法上。
原则五: 尽可能实现ToString()方法
如图,尽可能为所有的类重写ToString()方法,来输出详细信息。