在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
大家来讨论下C#无参属性这个东西到底有没有存在的必要? 永远不要公开类型的字段,面向对象设计和编程的重要原则之一就是 数据封装。如果公开类型的字段,会很容易的写出不恰当使用字段的代码。这里可以把字段声明为private,然后声明访问器方法。 class test 实现只读或只写就是这么简单,不实现一个索引器方法就行了。还可以将Setname方法标记为protected,就可以只允许派生类修改了。聪明的你也发现上面这个做法的缺点了吧,首先得去实现额外的方法,所以会产生更多的代码,其次,如果调用的时候必须调用方法,不能直接引用一个字段名。还好C#给我们提供了一个称为属性(property)的机制,它缓解了第一个缺点造成的影响,也消除了第二个缺点。 class test 属性可以用任意的可访问修饰符来标记。不能定义名称相同的属性。 如果只是为了封装一个支持字段而创建属性,C#还提供一一种更简单的语法,称为自动实现的属性(Automatically Implemented Property,简称AIP)。like this class test 如果声明一个属性而不提供get/set实现,C#会自动为你声明一个私有字段。原始代码是这样的: public int Age 和直接声明一个public 的Age字段相比,自动实现的属性的优势在哪?两者存在一处重要的区别:使用自动实现的属性(AIP)意味着已经创建一个属性,访问该属性的时候会调用get/set方法。如果有一天你决定自己实现这个AIP的get/set,而不接受编译器默认的实现,那么访问这个属性的任何代码都不必重新编译。如果是一个public的Age字段,如果你把它更改为属性,那么访问这个字段的所有代码就都需要重新编译了。 凡事都有好有坏,那么AIP有哪些不讨人喜欢的地方呢: 1.如果使用字段声明的语法,可以包含初始化的部分,如果使用AIP就不行了,必须在咩个构造器中显示的初始化每个AIP。 2.AIP支持的字段名是由编译器决定的,而且每次重新编译,这个字段名可能会发生更改,这样一来,只要含有一个AIP就不能对类型的实例进行反序列化了。在任何想要序列化或反序列化的类型中,都不要使用AIP功能。 3.不能在AIP的get/set添加断点,所以不好检测程序在什么时候获取或设置这个属性。咱手动实现的就可以设置断点,不信你试试。 AIP功能是作用于整个属性的:要么都用,要么都不用,这意味这,如果显式的实现get那么set也要显式实现,反之亦然。
属性看起来与字段相似,但本质上是方法。属性与字段的区别如下: 1.属性可以是只读或只写的(get/set访问器方法),字段却总是可读可写的。 2.属性方法可能抛出异常,字段访问不会抛出。 3.属性不能作为out或ref参数传递给方法,字段可以。 class Program 4.属性方法可能花费较长时间执行,字段的访问都是立即完成。 5.属性方法可能需要额外的内存,或者返回一个不正确的引用,指向不属于对象状态一部分的某个东西,这样一来,对返回对象的修改就作用不到原始对象身上了,相反查询字段返回的总是正确的引用,它指向的东西保证是原始对象状态的一部分。使用会返回一个拷贝的属性时,非常容易引起混淆。 如果仔细研究下属性和字段的差别,你会发现只有在极个别的情况下属性才真正有用。属性唯一的好处就是提供了简化的语法,和调用普通方法(非属性中的方法)相比,属性不仅不会提升代码的性能,还会妨碍对代码的理解。 属性访问器的可访问性: 我们有时希望为get访问器指定一种可访问性,为set访问器指定另一种访问器: class test 如上所述,Age属性本身声明为public,意味这get访问器方法是公共的,可由所有代码访问,但是,注意set访问器方法被声明为protected,只能从test的内部定义的代码中调用,或者从test的派生类的代码中调用。 定义一个属性时,如果两个访问其方法需要具有不同的可访问性,C#语法要求必须为属性本身指定限制最不大的那一种可访问性,然后在两个访问其中,只能选择一个来应用限制较大的那一种可访问性。在前面的例子中,属性本身为public,set访问器为protected(限制比public大)。 class test |
请发表评论