《C#高效编程》读书笔记01-使用属性而不是可访问的数据成员
在需求变更中,属性比数据成员更容易修改,例:客户对象不该与空白名称,若你使用公有属性封装Name,那么现在修改一处,而数据成员则可能要修改多处
public class Customer
{
private string name;
public string Name
{
get { return name; }
set
{
if(string.IsNullOrEmpty(value))
throw new ArgumentException("Name can not be blank","Name");
name = value;
}
}
}
因为属性是使用方法实现的,所以添加多线程支持也非常简单
public class Customer
{
private object syncHandle = new object();
private string name;
public string Name
{
get
{
lock(syncHandle)
return name;
}
set
{
if(string.IsNullOrEmpty(value))
throw new ArgumentException("Name can not be blank","Name");
lock(syncHandle)
name = value;
}
}
}
属性还可以拥有方法所有语言特性。例如:属性可以为虚的(virtual):
public class Customer
{
public virtual string Name { get; set; }
}
还可以将属性声明为抽象的(abstract),以类似隐式属性语法的形式将其定义在接口中
public interface INameValuePair<T>
{
string Name { get;set; }
T Value { get;set; }
}
还可以为get和set访问器定制不同的访问权限
public class Customer
{
public virtual string Name
{
get;
protected set;
}
}
还可以使用索引器(即支持参数的属性)
public int this[int index]
{
get { return theValues[index]; }
set { theValues[index] = value; }
}
//使用索引器
int value = someObject[1];
需要注意的是,所有的索引器都使用this关键字声明。C#不支持为索引器命名。因此,类型中每个不同的索引器都必须有不同的参数列表,以免混淆。
属性的功能很强大,但最后需要注意的是,如果之前是用数据成员实现,后面再改为属性,不能单一的编译一个程序集,必须把引用这个数据成员的所有程序集都重新编译。因为属性访问和数据访问会生成不同MSIL指令。