c# 字段和属性

来源:互联网 发布:iphone清单软件 编辑:程序博客网 时间:2024/04/25 11:47

一、字段(field)

    可以在声明字段的同时赋给它一个初始值。

二、属性(property)

1、引入

       假如将字段声明为public,则在类的外部都可以对该字段进行访问和更改,违背了类的封装特性。如果声明为private,则这种形式的封装通常又过于彻底。例如,你可能希望字段从外部只读,但从内部可以更改,但需要验证对数据进行的更改。

       以前,程序语言为了实现这些要求,采取的办法是将字段标记为私有,然后提供取值和赋值的方法来访问和修改数据。遗憾的是,这样做会影响类的可编程性。无法再用赋值运算符来设置类中的数据。另外,要想访问数据,只能调用方法来进行。

       考虑到经常会用到这种设计模式,c#的设计者决定为它提供显示的语法支持即属性。

2、构成

     属性的声明看起来和字段声明一样,但跟随属性名之后的是一对大括号。在大括号中,要添加具体的属性实现代码。两个可选的部分构成了一个属性的实现。其中,get标志的属性的取值方法部分,set标志着属性的赋值方法部分,它允许你调用字段赋值语法。

3、自动实现的属性

      它允许在声明一个属性时,不实际的实现任何取值方法或赋值方法,也不声明任何支持字段。

      例如:

  class Employee

{     public string FisrtName   //手动实现的属性

      { 

         get   { return _FirstName; }

         set  { _FirstName=value}

      }

     private string _FirstName;  //属性FirstName的支持字段

 public string LastName  { get;  set;} // 自动实现的属性

4、属性作为虚字段使用 即该属性没有支持字段

     在某些情况下,你甚至根本不需要一个支持字段。你可以让属性的取值方法返回一个计算好的值,而让赋值方法解析值,并把它持久存储到其他一些成员字段中。

例子:

class Employee

{     public string FisrtName   

      { 

         get   { return _FirstName; }

         set  { _FirstName=value}

      }

     private string _FirstName; 

     public string LastName   

      { 

         get   { return _LastName ; }

         set  { _LastName =value}

      }

     private string _LastName ; 

     public string Name//属性作为虚字段使用

    {

             get   {  returen   FirstName+ " " +LastName;}

             set

                {    string[]   names=value.Split( new char[] { '    '} );//  public String[] Split( params char[]  separator) 

                                                                                                           //separator :分隔此实例中子字符串的 Unicode 字符数组、不包含分隔符的空数组或Nothing
                                                                         // 返回值:一个数组,其元素包含此实例中的子字符串,这些子字符串由separator 中的一个或多个字符分隔。

 

                      if(names.Length==2)

                                 {  FirstName=names[0];   LastName=names[1];}

                      else   {  throw new System.ArgumentException (string.Format("assigned value '{0}'is invalid",value ) ) }

                  }

    }

}                

5、只读和只写属性

    通过移除某个属性的取值方法或赋值方法部分,可以改变属性的可访问型。只有赋值方法的属性为只写属性,这种情况很罕见。只提供取值方法的属性为只读属性,任何赋值企图都会造成编译错误。

6、为属性的取值和赋值方法指定访问修饰符

      (1)若不为属性的赋值和取值方法指定访问修饰符,则他们的访问修饰符默认为属性的访问修饰符。

      (2)在c#2.0中,可以为get或set部分指定访问修饰符(但不能为两者同时指定访问修饰符),从而覆盖了为属性声明指定的访问修饰符。例如,在一个属性中同时创建一个公共取值方法和一个私有赋值方法,是外部类只能对属性进行只读访问,而允许类内的代码想属性写入。

      (3)为取值或赋值方法指定访问修饰符时,这个访问修饰符的限制性必须必应用于整个属性的访问修饰符更严格。

7、属性和方法调用不允许作为ref或out参数值使用

      ref和out参数值在内部实现时,需要将内存地址传给目标方法。但是,由于属性可能是没有支持字段的虚属性,也有可能是只读或只写的,因此不可能传递其基础存储的地址。所以,不能将属性作为ref或out参数值来传递。同样地道理也使用于方法调用。如果需要将一个属性或方法调用作为ref或out参数值来传递,首先必须将值复制到一个变量中,然后传递该变量。方法调用结束后,在将变量的值赋回属性。

8、属性和其支持字段的命名规范

     假如属性名为FirstName,那么为该属性提供支持的私有字段来说,一些常见的命名规范是_FirstName和m_FirstName(延续自c++的一种命名规范,m代表member variable 成员变量)。另外,还可以采用camel大小写规范(除第一个单词外其余单词的首字母都大写)。不管为私有字段使用哪一种命名规范,都要依据pascal大小写规范(每个单词的首字母都大写)来命名公共字段和属性。

9、在类的内部关于字段的访问性问题

       作为一个良好的编程习惯,我们应该只在属性实现的内部访问为属性提供支持的字段。即 我们使用的应该一直是属性,而不要直接调用字段。许多时候,即使是在包容属性的那个类中,也不应该从属性实现的外部访问它所支持的字段。这样一来,在为属性添加了验证逻辑或者其他额外的逻辑后,整个类就可以马上利用那些逻辑。

10、属性和字段的区别

     @1、属性可以只读或只写,公有成员一定是可读写的。

     @2、属性里头你可以写代码 做自己的验证逻辑即 属性除了公布字段外,还可以在属性上添加对字段的约束规则,比如只读,只写,读写规则,还可以对属性的值范围设置等等。而字段则不可以

      总之,字段能干的,属性一定能干,属性能干的,字段不一定干的了。另外从软件设计的原则来看,属性是方法,应当暴露,而字段是数据应当被封装。