在C#中,属性是这样一种元素:他在被访问的时候看起来好像是数据成员,但他却是用方法实现的。.net中的数据绑定类只支持属性,而不支持公有数据成员。
将数据成员直接暴露给外界不符合面向对象的设计原则。
随着时间的推移,新的需求或行为往往会影响原来类型的实现,使用属性比较容易应对这些变化。例如,我们很快发现Customer类不能有一个空的Name。如果使用公用属性来实现,那么只需要在一个地方做更改即可。
public class Customer
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (value == null || value.Length == 0)
{
throw new ArgumentException("Name cannot be blank.", "Name");
}
_name = value;
}
//......
}
}
如果使用公有数据成员的话,我们就需要修改所有访问Name的地方。
由于属性是采用方法实现的,因此为他添加多线程支持就比较方便---直接在get和set方法中提供同步数据访问即可。
public string Name
{
get
{
lock (this)
{
return _name;
}
}
set
{
lock (this)
{
_name = value;
}
}
}
由于属性是采用方法实现的,所以属性具有方法的全部功能,可以实现为虚属性,抽象属性,或者作为接口的一部分。
利用属性还可以更好的控制对数据的访问权限:只读、只写、读写。。。
在.net 2.0里set和get可以有不同的修饰符,使属性的访问更具灵活性。
对于具有序列或字典特征的类型,则使用索引器。注意:所有的索引器都使用this关键字来声明,不能为索引器指定其他的名称,可以使用非数值索引器,也可以使用多维索引器,并且每一维上的参数类型可以不同。例如:
public int this[string index]
{
get
{
return _theValues[index];
}
set
{
_theValues[index] = value;
}
}
-------------------------------------------------------------
public int this[string name,int index]
{
get
{
return _theValues[name,index];
}
set
{
_theValues[name,index] = value;
}
}
访问属性和访问数据产生的是不同的MSIL。其效率没有很大的差别,只有在很少的一些情况下,这些效率才值得考虑。