C#封装:关于字段属性的get和set方法的小总结

时间:2022-12-30 14:54:06
----以下only个人学习完C#与JAVA时对属性中set 和 get方法的一些个人总结,如有误导或者不足之处,还请各位在评论区连嘲带讽的指出(不然咱没进步的空间啊T _ T)------

前提须知: 只有get方法叫只读属性,只有set方法叫只写属性,两个方法都存在叫可读可写属性

先看个例子:

           //  出于安全性需要,进行封装字段,我们把字段访问修饰符设成private私有,但是私有字段我们都知道只能在自己类中调用,于是我们就

           //  有了属性这个概念来进行对字段数值的赋值(set方法)和取值(get方法)

         public class Person


         {

                  /* 字段名我们一般用下划线开头 (在有些公司里也许会统一字段名开头小写的标准)  */

                  private  string _name;          

                  public string Name

                  {
                           get { return _name; }      /*get方法是对字段进行 取值时调用*/   
                           set { _name = value; }    /*set方法是对字段进行 赋值时调用*/
                  }

                 //    也许这时候您会问:这两个是方法吗,一般的方法至少是void fun( ){  } 这种吧,你这连个返回值类型和括号都没有叫什么函数,请您慢慢往下看
                 //    下面截图我们会通过 reflector这个反编译工具去看一下get 和set 这两个方法的本质

                  privatte int _age;
                  public string Age

                  {

                           get { return _age; }

                           set { _age = value; }
                  }

                  private char _sex;
                  public string Sex;
                  {
                           get { return _sex; }
                           set { _sex = value; }
                  }

                  private string _hobby;

                  public string Hobby

                  {

                           get { return _hobby; }

                           set { _hobby = value; }

                  }

                  private string _phone;

                  public string Phone

                  {

                          get { return _hobby; }          

                          set { _hobby = value; }

                  }

                // 用于打印值的show方法。注:这里就涉及到了get方法

                 public void show( )
                 {
                           Console.WriteLine("我叫{0},今年{1}岁,是个{2}生,兴趣是{3},电话是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone);

                 }

                 /****

                   *   构造一个Person函数,以便于实例化对象时进行传参.(结合下面)

                   ****/

10行       public Person (string Name, int Age, char Sex, string Hobby, string Phone)      /*先写个很全参数的构造函数,就方便20和30行的简写了*/

                {

                           this.Name = Name;

                           this.Age = Age;

                           this.Sex = Sex;

                           this.Hobby = Hobby;

                           this.Phone = Phone;          

                }

                 /* 当我们只想传递部分信息时可以创建多个构造函数,例如:只输入 姓名爱好, 号码时调用一个新的构造函数 */

20行       public  Person(string Name, string Hobby, string Phone) : this(Name, 0, '男', Hobby, Phone) 

                {

                }

                /* 再举个例子吧------>只输入姓名年龄性别 */

30行       public Person(string Name, int Age, char Sex) : this( Name, Age, Sex, "hobby",  "phone")    /* 继承参数最齐全的构造方法后,对自己没有的参数进行任意赋值 */

                {

                }

               /*****************************************

                 *     20行代码同等与下面代码,不过我们发现这样写会重复性写很多多余的代码,所以我们这里用this关键词写成20行的形式

                 *     这样可以有效的避免重复性操作,所以我建议不去下面这种形式 (我个人认为代码能多简洁就多简洁)

                 *      public Person (string Name, string Hobby,  string Phone )

                 *      {

                 *                this. Name = Name;

                 *                this.Hobby = Hobby;

                 *                this.Phone = Phone;

                 *    }

                 *****************************************/

                 // 下面这个用于输出的方法我就不优化了             

                public void show()
                {
                         Console.WriteLine("我叫{0},今年{1}岁,是个{2}生,兴趣是{3},电话是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone);   / *小黑*/

                         // Console.WriteLine("我叫{0},兴趣是{1},电话是{2}.", this.Name, this.Phone);  /*小红*/

                         // Console.WriteLine("我叫{0},今年{1}岁,是个{2}生.",this.Name,this.Age,this.Sex );  /*小粉*/

                }

         }

       


         class Program

         {

                  static void Main(string[ ]  args)

                  {

                           /*上面构造函数的好处在于,不需要使用 [对象名].方法名( ) 的形式进行赋值,类在创建一个对象时会先去调用类的构造函数*/

                           Person black = new Person("小黑",17,'男',"游戏","110");           // 调用第10行的构造函数

                           Person red = new Person("小红","绘画","120");                           // 调用第20行的构造函数

                           Person pink = new Person("小粉",21,"女");                                  //调用第30行的构造函数

                           black.show( );

                           red.show( );

                           Console.ReadKey( );

                 }

         }

      

看图说话 : 通过reflector这个微软员工写的反编译工具,我们可以知道   get; set; 这两个方法的实际执行代码,如上面的Name属性

我们写的是:

                  private  string _name;          

                  public string Name

                  {
                           get { return _name; }      /*get方法是对字段进行 取值时调用*/   
                           set { _name = value; }    /*set方法是对字段进行 赋值时调用*/
                  }

通过反编译我们可以知道它的本质代码是:

                 public string get_Name( )       

                 {

                           return  this._name;                   /*get方法返回的其实是字段*/ 

                 }

                 public void set_Name( string value )      /* 这里接收了对象实例化时调用构造函数的参数 */

                 {

                            this._name = value;               /*然后把值赋给了字段*/

                 }

C#封装:关于字段属性的get和set方法的小总结

C#封装:关于字段属性的get和set方法的小总结


      从以上对比,我们可以知道属性工作的流程。也许您会问知道这些有什么用呢。嘿嘿,我们知道属性和字段的关系之后,可以同过在属性上写点东西,达到对字段的约束作用。

例如:

      1. 让用户输入年龄时,用户可能输入负值如-17岁或者超过三位数如400岁这些不符合实际的数值,这时候我们就可以通过属性在用户输入时,通过set方法对输入的值进行约束。

Code部分:

        public int Age
        {
                get { return _age; }
                set
                {
                        if (value < 0 || value > 110)          /*在对年龄属性进行赋时可以进行判断*/
                        {
                                value = 0;
                        }
                        _age = value;
         }

       2. 在让用户进行填写性别时,输入的字符有可能是'公',而我们的目的是想显示'男'&'女',这时候我们就可以通过属性在打印时,通过get方法对输入的值进行约束.

Code部分:

         public char Sex
         {
            get
            {
                    if ( _sex  !=  '男'  &&  _sex  !=  '女' )
                    {
                             _sex = '男';
                    }
                    return _sex;
            }
            set {  _sex  =  value;  }
        }

总结一下

         那么什么时候对get方法进行约束,又什么时候对set方法进行约束呢。答:对属性进行赋值时对set方法进行约束,比如上面代码实例化对象进行传参 .属性进行读取数值时,用get方法进行约束,比如上面用show()方法进行输出时。

     

这次就写到这儿吧,脖子有点疼了。以上都是我学习的时候总结,留备自己再看.如有误区还请您在评论区指出或者补齐,这里感谢那些看完这篇blog的人,好吧你们说吧.