我设计的实体类没有用属性访问器get,set,
而是直接使用公有字段,
但是在这个类中不提供任何私有或公开的方法,只是声明了这些字段
public class EmployeeInfo
{
    public int EmployeeId ;
    public string Name;
}
大家来对这样的设计谈谈看法
嘻嘻,微软对这个问题是有解释的哟

解决方案 »

  1.   

    只是记得effective C#里说用public变量的地方最好定义成属性,这样性能会好一点
      

  2.   

    个人认为属性访问器
    其一是为了提供只读或只写。
    其二是为了进行某些的初始化或批处理,例如赋值后还要刷新、数值检验等。相当于函数。
    其三便于理解。
    属性访问器就是个函数。
    处以上原因,个人认为没有必要使用属性。
    public int EmployeeId ; 
    这类东西相对简单,直观。可以事前初始化,也可以事后赋值。
    轻量级的通常多变方便,重量级的规范、功能强大。
    看怎么用了。
      

  3.   

    关于.Net中属性的使用探讨:http://www.chinaitpower.com/A/2002-03-03/15619.html
      

  4.   

    纯粹为了Mark一下.还在考虑,在多线程环境下,会不会是有不同的效能的?
      

  5.   

    effective C#第一条就是属性优于字段MS的解释我倒是没看见过想听听楼主高见
      

  6.   

    15楼的我没太看懂,在我看来变量也是这样的啊个人认为属性其编译后是当做方法使用的,其并不是存在地址段上的,好像是存在代码段的.记不住了
    恩,理解成方法似乎强大了很多.毕竟GET SET 里面能写很多东西
      

  7.   

    正如15楼所说,我这样做就是要获得函数参数可以传址引用实体字段的便利,
    从表面现象看,ref(out)和公开实体字段这两条在微软看来(或大多数开发者)
    都是BadDesign,
    1.关于字段的问题微软是这样解释的:
    字段的主要用途应是作为实现的详细信息。字段应为 private 或 internal,并应当通过使用属性来公开。访问属性和访问字段一样容易,且随着类型的功能扩展,无需引入重大更改即可更改属性访问器的代码。仅返回私有或内部字段值的属性经过优化,可以像访问字段那样执行;在属性上使用外部可见字段不会提高性能。
    但是微软又指出,当"您不依赖于该字段的内容"的时候这就不属于BadDesign,当然这只是必要条件,
    充分条件是您能从这种设计中获得属性访问器无法获得的好处,
    在我的设计中获得了传址引用的便利,因为属性是函数,无法传址
    2.关于Ref的问题微软是这样解释:
    通过引用(使用 out 或 ref)传递类型有以下要求:具有使用指针的经验,了解值类型和引用类型的不同之处,以及如何处理具有多个返回值的方法。另外,out 和 ref 参数之间的差异没有得到广泛了解。
    此设计可能会导致可用性问题
    但是微软又认为
    当您使用大型结构参数时,复制这些结构所需要的附加资源在您按值传递时可能会造成性能影响。在这些情况下,您可以考虑使用 ref 或 out 参数
      

  8.   

    属性是函数,是不能作为ref参数引用的
      

  9.   

    这样设计的实体类最终会导致不能使用微软最强大的功能之一,数据绑定List<EmployeeInfo> allEmps=new List<EmployeeInfo>();this.dgvAllEmp.DataSource=allEmps;
    this.dgvAllEmp.DisplayMember="EmployeeId"; //这儿只能指定属性或者是表的列名
      

  10.   

    有点意思哈。
    简单的反成IL代码看了下。就是callvirt和ldfld的差距。在构建大量对象的时候,这两个code的开销能差多少?楼主有做过实验?
      

  11.   

    个人认为属性访问器 
    其一是为了提供只读或只写或者两者者包括。 
    其二是为了进行某些的初始化或批处理,例如赋值后还要刷新、数值检验等。相当于函数。 
    其三便于理解。 
    属性访问器就是个函数。 
    处以上原因,个人认为没有必要使用属性。 
    public int EmployeeId ; 
    这类东西相对简单,直观。可以事前初始化,也可以事后赋值。 
    轻量级的通常多变方便,重量级的规范、功能强大。 
    看怎么用了。但是我觉得还有提高维护性
    可读性
      

  12.   

    我只是说属性是干什么的
    属性可以提供公共数据成员的便利,而又不会带来不受保护、不受控制以及未经验证访问对象数据的风险。这是通过“访问器”来实现的:访问器是为基础数据成员赋值和检索其值的特殊方法。使用 set 访问器可以为数据成员赋值,使用 get 访问器可以检索数据成员的值。别的啥也没说 别激动
      

  13.   

    很多看似Bad的设计其实对于他所处的生产线而言可能是最佳方案
    其实每个开发者自己回味一下
    你是如何设计实体的,
    就能体会到,
    当项目越来越复杂,你设计的难度就越来越大,
    你所使用的技术手段也越来越复杂:
    什么分层、接口、反射、泛型……
    而且需求变化的可能性也越来越大。
    当我们的生产手段发生重大变革以后,
    很多传统的设计思路都需要重新审视才能进一步提高生产效率,
    在不同的生产手段下,应用相同的理论基础,却能得出截然不同的方案,
    就像有人说日本人写软件很变态,光写函数,不封装类
    不管这是不是真的,有一点可以肯定,他需要的零部件一定是和他的生产线相配套的;
    我们的软件制造业成熟度不高在于:很少有人以工业化或自动化生成的角度看待软件开发,
    这种观点或技术只是被少数公司或技术人员掌握。
    我在这里只是以一个很小的貌似Bad的设计,来抛砖引玉,引出大家对
    软件开发的新思维新讨论
      

  14.   

    32楼cancerser:您误会了,我没激动,
    大家来讨论我求之不得,谢还来不及呢
      

  15.   


    控件数据源绑定实体方案?
    N层架构中实体类很大的作用就在于取代原有的数据集和强类型数据集
    那么,实体对象作为实际数据的体现,如何在UI层体现,不论是Winform还是Asp.net,都可以快速方便地使用的数据绑定无疑是首选
    Effactive C#的说法还是有它的依据的
    public class EmployeeInfo 

        public int EmployeeId ; 
        public string Name; 
        public int age;
        public int Age
        {
            get{return age;}
            set{age=value;}
        }
        
        //是否成年
        public bool IsGrowing
        {
            get{return age>=18;}
        }
    } 可以提供对数据的另外一种映射,甚至于属性的数据来源可以根本上不用是字段例如在于asp.net,可以在自定义控件或者是页面中采用类似这样的封装
    public int Page
    {
         get
         {
            if (Viewstate["Page"]==null)
                Viewstate["Page"]=0;
            return Convert.ToInt32(Viewstate["Page"]);
         }
         set{ Viewstate["Page"]=value;}
    }
    如果限定“他所处的生产线”,囧
    讨论山地自行车和F1赛车在田埂道上谁更合适.....
      

  16.   

    我有一个List<EmployeeInfo >的集合 需要把里面的数据现实到datagridview中
    如果不用属性的话 是不是不好实现?
      

  17.   

    楼主这样有点钻牛角尖了,如果公开你的字段,就意味着外界对于这些字段的值可以随意设置,隐患很多,现代程序设计讲究的是稳定性和可扩展性,并不是为了那一点点的技巧而抛弃原来应该有的设计方法。
    如果为了技巧和速度,比如值引用和指针引用这样的问题,那就不应该选择.net了。用C来实现最好。
      

  18.   

    40楼cloneCenter:
    我并不认为你的说法和我的设计冲突,
    我在98年开始做windows平台的App开发(之前是Xenix平台开发)
    就在用get,set封装字段,这样的设计是和我当时的生产手段相配套的,
    做了那么多年开发我受够了一个开发者所承受的痛苦,扪心自问,问题出在哪里呢,
    对照成熟的传统制造业,发现我们的部件组装过早、组装工序过少,是导致我们不能适应
    复杂多变的用户需求的重要原因。
    而现在我的类实体已经和方法分离,方法不再依赖实体属性(所以是静态的),我原先设计的类
    被分解到Model、BL、DA三个部分:
    Model中就是你们上面看到的那个样子的实体;
    BL实现业务逻辑:比如如何产生一个C#的代码片段(并没有调用DA的方法);
    DA实现所有数据访问的方法;
    在这里,每个方法都被设计成原子化的功能,
    实体和表基本是映射的,因为它们都是从我的数据模型生成的,
    DA的方法也基本是和SP映射的,因为它们也都是从我的方法模型生成的(但是比较复杂的
    SP还是需要自己填写内容);
    这三个部分的耦合度非常低,基本上还处在一般散沙的状态,为什么要这样做呢?
    就是要推迟组装,增加组装工序,至于怎么组装,我的组装工序又有哪些不是我今天想和大家讨论的,
    我想今后大家有的是机会的讨论;
      

  19.   

    38楼showlin:
    我在帖中已经说明了我的先决条件,
    依照您说的情况,我同意你这样做是符合您的开发手段的,
    而且我也这样做了10多年,
    可是我现在这样做对于我的开发体系就不合适了
      

  20.   

    showlin(说武林)您在25楼38楼分别提到数据绑定的问题我是这样看的:
    1、表格呈现的只是视图(表格只是其中一种方式),
    它的内容(行和列)都是由用户决定的,而且很多情况下都属于用户的个性化配置,
    比如一个数据库应用程序可能会有超过一百个gridview(这也很正常),
    他们的内容能和您的实体对应吗?或者说您是按照UI视图的内容设计实体??
    还是您要二者兼顾一下???
    2、每次查询可能会返回结构不同的数据集,甚至对同一个字段的描述都会不同,
    那应该怎么设计实体呢?对于多表连接的视图又如何处理呢
    我的意思不是这些问题解决不了,肯定您有你的解决方法,
    但我以前考虑这种方案的时候在想,到底是我设计实体还是实体设计我啊?!
    用户如果需要对一个表格做比较大的调整,我只需要改一下SP就行了,用户自己改一下配置就OK了
      

  21.   

    我本来是想请大家讨论一下什么情况下用属性什么情况下可以公开字段的,
    说实在的,我并不想讨论那种是好的设计那种是坏的设计,
    43楼tryanother说得很对极了,
    以前看不少人吵吵Java和C#那个好,觉得这不是我们应该关注的重点。
    我觉得这么些年开发工具换啦一茬又一茬,我们好像还是在手工作坊里干活,
    程序员就不应该是看苦力吃青春饭的,他们应该过着轻松富足的日子,
    我不为自己考虑,也要为和我一起奋斗的同仁考虑,我们的目标应该是:
    没有蛀牙……,哦不好意思说错了,应该是干少量的活,挣多多的票子。
    面向对象的理论我们自以为再熟悉不过了,可是有谁真正能把它很好的应用起来呢?
    大多数我们都在用的是结论,而非理论,
    结论往往是建立在一些必要条件(或者再加上一些充分条件)的基础上推导出来的。
    就像所说“如果公开你的字段,就意味着外界对于这些字段的值可以随意设置”,
    可我就是公开字段就是提供给外界使用的,实体内部根部就不用他,那么怎么能得出
    “隐患很多”的结论来的呢?所以我的设计:方法与数据结构分离产生的隔离效果
    不就是等同于那个属性访问器吗,另一方面我这样做大大降低了不良耦合,其实我并没有
    完全分离,而是推迟组装和多道工序组装,这样做又大大提高了程序的可扩展性,同时也避免
    前台要面对一大堆零部件的情况(在每个模块,后道工序拿到的都是专门为他们准备的零部件或组件)
      

  22.   

    传址的方式有很多,放到类里未必是最好的方法.sp1234一定会说:花时间研究这点东西,能节省1ms不?  还不如用这个时间和精力写个缓存.
      

  23.   

    在应用到Dlinq的时候,一样有这样的类存在的,我举个例子:
    假设Sql Server中有一个表Customer,其中有很多字段,但这里我们只需要少量的字段(如下类中所示,ID做为主键)
        [Table(Name = "Customer")]
        class Customer
        {
            [Column(IsPrimaryKey = true)]
            public string ID;        [Column()]
            public string CompanyName;        [Column()]
            public string Contactor;        [Column()]
            public string Address;        [Column()]
            public string City;        [Column()]
            public string Zone;        [Column()]
            public string Phone;    }
      

  24.   

    其实在dlinq中,可以用.net自带的命令来生成元数据文件与数据表映身的,只不过我是自己写的类实现与数据表映射的,但实质大同小异而已;
      

  25.   

    还是没发现这样设计的意义除了ref以外还有别的好处吗?
      

  26.   

    刚接触到Linq的时候还蛮激动的,我一直想建立表和实体的映射,
    当时由于没有考虑代码自动化问题,走了不少弯路,
    可后来有了代码生成就不一样了,
    我的实体和表,是从数据模型导出生成的,而且自己生成代码
    既能符合要求又有很大的灵活度;
    微软生成的代码不符合我的代码规范,并且是数据库驱动的,不符合我的驱动模式
      

  27.   

    一般来说可以这样讲,在类里面声明的,是字段,在方法里面声明的,是变量。   
    字段有访问修饰符(public/private/protected/internal),变量没有。   
      

  28.   

    56楼fskang:
    一套设计体系很多环节都是相互配套关联的,
    简单的说一下我的设计的几个要点:
    1、属性和方法分离(使得字段公开成为合理设计);
    2、根据业务需要推迟组装和多工序组装,
    出最后一道工序(UI)目前还是手工组装,
    其他的都已实现自动化;
    3、方法通过参数约定最后一道工序需要哪些数据,
    影响了哪些数据(ref参数)其实:实体在我的设计体系中已被弱化,我的设计有两条组装线路:
    原子化的方法-->组装-->再组装;
    原子化的控件-->组装-->再组装;
    实体只是为最后UI层总装提供UI和业务处理隔离的便利,
    程序员不嫌麻烦可以自己声明一大堆局部变量来隔离,不一定使用实体,
    换句话说,如果最后总装也自动化了,我就连实体都可以不要了
      

  29.   

    flashlove2008:
    我们讨论的是属性和字段,不是字段和变量
      

  30.   

    ref结构即可。。貌似属性有两个控制get与set 可能方便一些,还有可能更符合描述对象。
      

  31.   

    我觉得并非如此 没必要当结构去, 函数参数的结构照样可以用ref,让结构像引用类型一样传递引用。
      

  32.   

    1.属性能更好的隐藏字段,免于字段直接暴露个客户端。不安全。
    2.属性可以提供更细力度的控制。
    3.属性在多线程的实例里可以给字段加锁提高线程安全。
    4.属性里进行一些处理免于一些敏感应用类型字段直接暴露给客户端。比如dataset.
    5.属性可以进行一些有效性校验,优于直接给公共字段赋值。
    6.接口里应用属性可以规范属性签名,便于继承的统一。
      

  33.   

    个人感觉,直接用字段的情况,还是应该限制在内部类(并且很可能是private的nested类),公开类型上暂时不考虑这种方式直接用字段带来的可以ref的好处(就是il的ldflda),但是在实际编程中涉及的并不多
    而性能方面的提升,也可能因为jit的inline优化而导致不明显(事实上,如果关心这点性能损失的话,就应该去用c++写)
    相反,带来的副作用有时候可能是很麻烦的。
      

  34.   

    呵呵,但是我觉得除了ref这个好处以外,我实在看不出它还有什么字段能做属性不能做的。反过来说,属性可以隐藏实现,限制访问权限,延迟初始化,甚至进行aop等等,这些字段是做不到的。还有你说到组装的思想我很赞同,我一直觉得一个工程性软件结构是非常非常重要的。但是这里有个层次的问题,你觉得一个如此微观的设计能够对你的整体结构产生决定性影响吗,就像飞螺丝钉对于大楼是非常重要的,但是建筑师会把大量的经历放在螺丝钉的设计上吗?另外,非常钦佩楼主的研究精神,希望csdn有更多这样的帖子。
      

  35.   

    首先感谢85楼fskang的认真参与讨论的态度,
    我想这个贴对我们很多程序员都有参考价值
    其次您对属性的观点我是赞同的,我也是一直这样认为的,
    属性访问器就是将实体内部对字段的处理与提供给外界的处理隔离,并能够对外界操作进行控制,
    但是这是建立在一个前提条件(当然这个前提条件出现的非常普遍),就是实体内部有依赖于
    字段的方法,或者将来可能出现依赖于字段的方法;
    一旦这个条件不存在了(属性与方法分离),属性能提供的好处也就不存在了
    ;
    我最初在类里面设计了一个不依赖字段的方法,.net代码分析器提示我应该将这个方法定义为静态的,
    于是我干脆把所有方法与属性分离设计,结果发现整个项目的类的设计难度大幅度降低,
    并且可以自动化所有的实体类(数据描述)和服务类(实现方法),
    我拿这个例子来讨论是想看看大家是不是清楚属性访问器的优势是建立在什么基础上的,
    也希望能给大家一些启发,(当然大多数情况,类里面都是有代码的,属性设计应该优先考虑)
    因为我发现我平时很多根深蒂固的所谓面向对象的思想
    其实是形而上学地套用一些结论,不讲场合地应用这些结论到头来反而束缚了我们的手脚、
    我们的思想,
    我最明显的感觉就是以前随着项目的规模增加,类的设计越来越麻烦,
    幸运的是我现在不用为这种问题烦恼了。
      

  36.   

    引用 15 楼 lianshaohua 的回复:
    就是当成结构来用,只不过在做为函数参数的时候是引用传递,非结构的值传递,提高些效率; 
     有些道理。
    学习了