在程序中,难免要访问某个对象的私有成员。那么以前实现这类功能的方法有两种,第一种方法最简单,就是把成员访问符从“private”改为“public”即可;而另一个就是提供公有的成员访问函数来进行访问。那么现在用C#编写程序,就不再需要采用前面所说的两种方法了,而直接使用属性来完成。
首先来看看三种方法的如何实现以及调用的,这里用一个例子来说明,即访问“EmployeeInfo”类的私有成员strName,具体如下表格所示。
\n
private string strName; | 访问方法 | |
修改成员访问符 | 修改: private string strName; 为: public string strName; | EmployeeInfo empNew…; string strNameValue = empNew.strName; empNew.strName = “me”; |
公有成员函数 | 增加如下两个成员函数: public string getName() { return strName; } public void setName( string Name ) { strName = Name; } | EmployeeInfo empNew…; string strNameValue = empNew.getName(); empNew.setName( “me” ); |
属性 | 增加如下属性: public string Name { get{ return strName;} set{ strName = value; } } | EmployeeInfo empNew…; string strNameValue = empNew.Name; empNew.Name = “me”; |
那么这三种方法有什么区别呢,用如下的表格,可以更好的说明三者的区别。
\n
类的封装性 | 代码安全性 | 代码繁琐性 | 代码效率 | |
修改成员访问符 | 破坏类的封装 | 存在潜在危险 | 简便 | 最高 |
公有成员函数 | 没有破坏 | 安全 | 繁琐,而且调用不直接 | 最低 |
属性 | 没有破坏 | 安全 | 简便 | 仅次于第一种方法 |
因此可以看出使用属性不但没有破坏类的封装性,没有减弱代码的安全性,而且和第一种方法一样简便,只是在效率方面要略低于第一种方法。但总体看来,在C#中用属性来访问类的私有成员是不二的选择。
不过对于使用属性,以及如上表格所说的,难免会有人产生如下一些疑问。
疑问一:就是用属性是否能达到成员函数那样的效果,即完成复杂的代码操作。
其实属性的底层实现是借助于成员函数,只不过这部分转换是由系统帮忙做的,所以在编写属性的时候,可以像编写成员函数一样,即在成员函数中所能写的代码片断,完全可以在属性中套用。下面就贴出属性所转换的微软中间语言(MSIL)代码。
\n
.property instance string Name()
{
.get instance string NameSpace.EmployeeInf:get_Name()
.set instance void NameSpace.EmployeeInf:set_Name(string)
}// end of property EmployeeInf:Name
.method public hidebysig specialname instance string get_Name() cil managed
{
…
}// end of method EmployeeInf:get_Name
.method public hidebysig specialname instance void set_Name(string ‘value’) cil managed
{
…
}// end of method EmployeeInf:set_Name\n
{
.get instance string NameSpace.EmployeeInf:get_Name()
.set instance void NameSpace.EmployeeInf:set_Name(string)
}// end of property EmployeeInf:Name
.method public hidebysig specialname instance string get_Name() cil managed
{
…
}// end of method EmployeeInf:get_Name
.method public hidebysig specialname instance void set_Name(string ‘value’) cil managed
{
…
}// end of method EmployeeInf:set_Name\n