none
MVP专家讲坛-关于字段封装属性 RRS feed

  • 常规讨论

  • 在c#中,我们在设计类时,一般都要把字段定义成私用的,然后再封装成属性,在这个时候,常有人想,把字段定义成公有不就行了?想对这个问题,大家讨论一下!

    山西.net俱乐部
    • 已更改类型 YiChun Chen 2010年4月5日 10:55 Discusstion topic
    2010年4月2日 12:36
    版主

全部回复

  • 沙发!

    set 可写,get可读

    字段可以用 readonly只读

    但好象做不到只写 楼下继续

    2010年4月2日 12:44
  • 为了字段的安全性吧.不能让他直接访问字段.
    2010年4月2日 12:56
  • 在某一个类中,字段是私有的,而属性是公有的,属性在一定程度上具有安全性,比如可以根据属性来设置该字段是否 set(赋值) 或get(返回)。

    使该字段具有安全性。而且字段只有声明 赋值, 而属性可以有其他操作,就比如判断。

    简单例子:
    class Test
    {   
       private int age; //字段   
        public int Age //属性   
        {       
          get { return age; }       
          set {
                 if(age > 50 && age < 100)
                  {
                    age = value;
                  }
                 else
                  {
                    age = 20;
                  }
              }   
        }
    }
    所以我个人觉得这两种情况怎样做要看情况而定,如果只是简单的存取数值可以直接声明称public,如果需要其它复杂的操作就把字段封装成属性。总之怎么方便怎么来吧!

    2010年4月2日 13:20
  • 一般在C#中,想“暴露”类中的某些数据给用户可以使用两种方式来实现,一种是使用公有字段,另外一种是使用属性来实现,下面我列举一些代码来比较 这两种实现:

    1,使用公有字段:

    public class Student

    {

         public string Name;

    }

    2,使用属性:

        public class Student
        {
            private string _name;
            public string Name
            {
                get
                {
                    return _name;
                }
                set
                {
                    _name = value;
                }
            }
        }

    客户代码都是 一样的:

            static void Main(string[] args)
            {
                Student studentOne = new Student();
                string name = studentOne.Name;
                studentOne.Name =inputString;
            }

    看上去似乎直接使用公有字段更简洁些,但是请大家留意这种情况,比如过一段时间需求更改为不允许对Name设置空值,使用公 有字段就需要修改客户代码了:

            static void Main(string[] args)
            {

                Student studentOne = new Student();

     

                string name = studentOne.Name;

                if(inputString!=null&&inputString.Length!=0)

               {

                     studentOne.Name = inputString;

                }

            }

    如果客户代码中有多处设置Name的地方,那每一处都需要修改,使用属性的 话只有修改属性的定义就可以了!这就是属性带来的便利!
    周雪峰
    2010年4月2日 13:25
    版主
  • 简单来说将字段设为属性的目的就是为了封装,说白了就是更加灵活的控制字段的可访问性。

    2010年4月2日 14:05
  • 看具体应用吧,穿西装或者穿便装,各有用处……
    霸王
    2010年4月2日 16:39
  • 一般来说,若是类是共有的,可能会被不同的客户端代码调用,那么用属性会比较好。

    就如同楼上周雪峰的示例代码中,有可能暴露给客户端的get或者set需要进行修改。用属性的话,客户端代码可以不用修改,达到最好的封装效果。

    另外一种情况是,自己写的私有类,作为临时包装几个字段所用,就无所谓了。


    MCPD (Windows & Web)
    2010年4月3日 4:09
  • 感觉get set可以更加严密些,比如在SET中添加限制,这样可以保证字段值的安全,像年龄
    2010年4月7日 11:15
  • 其实我在疑惑一个问题,把字段封装成属性会不会降低效率。

     

    2010年4月12日 12:37
  • 大家回答的都不错,各有道理。

    我在这里说一下我的理解,可能有不合理的地方,仅供参考。

    我觉得,从一定角度去想一个程序,其实是有两部分组成,一部分是数据,另一部分是运算逻辑。

    数据这部分呢,在C#中是用过字段存放的(当然还有方法内局部变量,但它不是对象的状态数据,只是在运算中的辅助数据),在这里,如果从业务角度考虑,每个字段,都有对应有一个准确的业务含义。就像有的人举的例子,name,age,都有业务含义,只要有含义,用数据表示出来,就有一定的限制,比如姓名,没有以数字,或计算机上奇怪字符充当姓名的,比如我,不可能叫@#$%&*()_+桂素伟,相信老外也没有这样的叫名字的,所以我们对姓名有一定的限制。年龄更是了,没有负的,没有超过150的(当然,这里说的是人,不是龟,听说龟可以活万年),所以我觉得,只要表达业务的数据,都是有限制的(关于数据的限制,一般是用正则做到的)。

    即然都有限制,在这里用属性封装字段就用很大的必要了。还有一点好处是可以是只读的还是只写的,限制数据的方向,这点也很重要。

    当然对于效率来说,直接访问,肯定要比封装起来访问好点,但有些东西是不能省的,验证数据的有效性,就是通过属性封装来做到的,也就是这里说的属性来做到的,所以这块牺牲点效率来换处数据的有效性,是值得的。



    山西.net俱乐部
    2010年4月13日 15:57
    版主
  • 其实我在疑惑一个问题,把字段封装成属性会不会降低效率。

     

    基本不用担心这个问题,一般属性的访问器都不复杂,多数情况下都可以在编译的时候内联掉,这样就没有方法调用的性能开销了!

    周雪峰
    2010年4月21日 11:18
    版主
  • 我在想一个问题,为什么字段象年龄都有前面if判断了,我门在写程序的时候不是还要加一层判断么,是否大于100小于0 给用户提示,set里加的IF还有必要么,本身我门也要去判断是否超出给用户提示呀,所以年龄也根本不可能超出
    2010年4月22日 1:28
  • 看来你没有看清楚前面的回复,你在写程序的时候要加判断?假如有100个地方需要使用这个属性,你写100个判断?还是专门写一个判断的方法?那么为何不把他放在自己的set里面去判断。需要判断年龄的是属性本身!不是调用者。
    2014年2月21日 3:21
  • 面向对象的三个基本特征:封装,继承和多态。

    你这里的问题涉及到第一个特征:封装。

    在面向对象的设计领域中,“字段”表示对象的“状态”,根据封装的定义,类可以把自己的状态和方法只让可信的类或者对象操作,对不可信的进行状态隐藏。所以,如果你的“字段”定义为公有,那么类将无法实现封装的特性。

    2014年2月21日 3:46