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"; |
类的封装性 | 代码安全性 | 代码繁琐性 | 代码效率 | |
修改成员访问符 | 破坏类的封装 | 存在潜在危险 | 简便 | 最高 |
公有成员函数 | 没有破坏 | 安全 | 繁琐,而且调用不直接 | 最低 |
属性 | 没有破坏 | 安全 | 简便 | 仅次于第一种方法 |
.property instance string Name() { .get instance string NameSpace.EmployeeInfo::get_Name() .set instance void NameSpace.EmployeeInfo::set_Name(string) }// end of property EmployeeInfo::Name .method public hidebysig specialname instance string get_Name() cil managed { ... }// end of method EmployeeInfo::get_Name .method public hidebysig specialname instance void set_Name(string 'value') cil managed { ... }// end of method EmployeeInfo::set_Name |
如上就是前面EmployeeInfo类的Name属性所转换的中间语言代码(不过省略了函数的具体实现代码,因为这里并不是为了研究中间语言代码,如果需要对这部分有更多地了解,参看中间语言相关书籍)。
精品教程尽在www.xvna.com
疑问二:就是用属性的效率是否仅次于第一种方法。
从上面很容易看出,属性在编译的时候会转换成和成员函数一样的代码,那么它的效率应该和成员函数是一样的。其实并不是这样,因为JIT编译器会把属性所转换成的两个成员函数作为内联函数,这样效率会提高很多。(注:内联函数是代码被插入到调用者代码处的函数,通过避免函数调用所产生的额外开销,从而提高执行效率。不过书中也提到,即使不是内联函数,成员函数相对于方法一的效率损失也是微乎其微的。)
用C#写程序,一提到属性,大家都会编写。其实在属性中,可以产生很多应用,接着来就分别说明。
<!--[if !supportLists]-->1. <!--[endif]-->在属性中使用索引符,例如像“ArrayList[i]”来访问ArrayList某个成员。这里需要注意的是,属性名以及索引参数的编码格式是固定的,如“this […]”。不过索引参数可以是多个,而且不光支持整型参数,还可以使用其他类型参数。例如:
public ReturnValueType this[ ParType1 parValue1, ParType2 parValue2] { get{...} set{...} } |
public string Name { get { lock(this) { return strName; } } set { lock(this) { strName = value; } } } |
public class class1 { string _data; public class1( string data ) { _data = data; } public string Data { get{ return _data;} set{ _data = value;} } } public class class2 { private class1 myClass1 = null; public class1 Class1 { get{ return myClass1; } } public string Data { get{ return myClass1.Data;} } public class2( string data ) { myClass1 = new class1( data ); } } |
class1 myClass1 = myClass2.Class1; myClass1.Data = "test2"; |
public class class1:ICloneable { string _data; public class1( string data ) { _data = data; } public string Data { get{ return _data;} set{ _data = value;} } #region ICloneable Members public object Clone() { // TODO: Add class1.Clone implementation return new class1( _data ); } #endregion } public class class2 { private class1 myClass1 = null; public class1 Class1 { get{ return myClass1.Clone() as class1; } } public string Data { get{ return myClass1.Data;} } public class2( string data ) { myClass1 = new class1( data ); } } |