积木首页 | 500多种网页特效 | 函数手册 | 广播电台 | 高清晰图片素材 | 服务器合租 | 万年历 | 网友最新浏览记录
程序开发 网页设计 搜索引擎 特效代码 操作系统 防范病毒 黑客技术 图形图象 电脑硬件 网络技术 服 务 器 数 据 库 网文精粹
您的位置:积木首页 >> 程序开发频道 >> .NET >> 正文:
标题:C#箴言之用属性来访问类的私有成员(2)
时间:2006-6-17 来源:酷网动力 浏览数:
     疑问二:就是用属性的效率是否仅次于第一种方法。
  
    从上面很容易看出,属性在编译的时候会转换成和成员函数一样的代码,那么它的效率应该和成员函数是一样的。其实并不是这样,因为JIT编译器会把属性所转换成的两个成员函数作为内联函数,这样效率会提高很多。(注:内联函数是代码被插入到调用者代码处的函数,通过避免函数调用所产生的额外开销,从而提高执行效率。不过书中也提到,即使不是内联函数,成员函数相对于方法一的效率损失也是微乎其微的。)
  
    用C#写程序,一提到属性,大家都会编写。其实在属性中,可以产生很多应用,接着来就分别说明。
  
    <!--[if !supportLists]-->1. <!--[endif]-->在属性中使用索引符,例如像“ArrayList[i]”来访问ArrayList某个成员。这里需要注意的是,属性名以及索引参数的编码格式是固定的,如“this […]”。不过索引参数可以是多个,而且不光支持整型参数,还可以使用其他类型参数。例如:
  
  public ReturnValueType this[ ParType1 parValue1, ParType2 parValue2]
  {
   get{...}
   set{...}
  }
  
    <!--[if !supportLists]-->2. <!--[endif]-->可以给属性操作加上互斥锁,以防止多线程操作时而产生的并发错误,具体如下。
  
  public string Name
  {
   get
   {
    lock(this)
    {
     return strName;
    }
   }
   set
   {
    lock(this)
    {
     strName = value;
    }
   }
  }
  
    <!--[if !supportLists]-->3. <!--[endif]-->书上还提到属性的其他应用,例如:通过接口来实现在一个类中同时提供只读属性以及非只读属性。但是我个人认为,虽然这样可以实现,但是会产生歧义,即在一个类中提供两个不同版本的属性,破坏了类的一致性,所以我并不推荐这么做。
  
    接着,要说说编写属性的时候,需要注意些什么,我个人认为有如下两点大的方面。
  
    第一个就是编写属性get部分的时候,如果当前属性的类型是引用类型的话,且不想通过属性来修改局部成员的话,最好返回局部成员的copy,而不是成员本身。
  
    例如:
  
  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 );
   }
  }
  
    如果按照如上所写,那么class2对象可以通过Class1.Data属性访问和修改局部成员myClass1某些值,这样就可以修改了myClass2的私有成员myClass1的值,即会产生潜在错误。
  
    例如:
  
  class1 myClass1 = myClass2.Class1;
  myClass1.Data = "test2";
  
    如何避免这类错误呢,那么首先需要修改Class1属性的编写,其次在class1类需要提供Clone函数或者其他copy函数,具体如下:
  
  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 );
   }
  }
  
    第二个需要注意的是编写属性set部分的时候,这里需要对参数进行有效性检查。因为属性是外界修改类的私有成员的入口,为了避免因为私有成员不正确而产生的错误,所以在进行属性set的时候要进行有效性检查,从而保证私有成员对于整个类来说是有效的。
  
    那么在实际应用当中,与属性密切相关的就是实现两个窗体之间数据访问,这可能是写WinForm程序最基本的。不过很遗憾的是,网上在回答此类问题的时候,很多人都建议用第一种方法来解决。
  
    


(责任编辑:笑虎)
关于本站 | 广告服务 | 联系我们 | 版权申明 | 强强联盟 | 投稿热线 | 网站地图 | 申请链接
Copyright ©2005-2006 Gimoo.net All rights reserved. 积木网 版权所有
E-mail:gimoohr@gmail.com 京ICP备05050695号