博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Effective C#》读书笔记——条目1:使用属性而不是可访问的数据成员<C#语言习惯>...
阅读量:6528 次
发布时间:2019-06-24

本文共 2905 字,大约阅读时间需要 9 分钟。

  属性允许将数据成员作为公共接口的一部分暴露出去,同时仍旧提供面向对象环境下所需要的封装。属性这个语言元素可以让你像访问数据成员一样使用,但底层依旧使用方法实现。通过使用属性我们可以创建出类似于数据访问(客户代码在访问属性时,就像是在访问共有的字段),但实际上确是方法调用的接口,自然也可以享受到方法调用的所有好处。

  在.NET Framework中,数据绑定类仅支持属性,而不支持公有数据成员。对于所有的数据绑定类库均是如此,包括WPF、Windows Forms和Silverlight。

关于数据绑定:

数据绑定就是将某个对象的一个属性和某个用户界面控件相互关联起来。数据绑定机制使用反射来找到类型中的特定属性

  下面的代码表示:将txt_City控件的Text属性绑定到了Address对象的City属性上。

this.txt_City.DataBindings.Add("Text", address, "City");

 

  使用属性使我们可以更容易应对变化,当日后产生新的需求或行为时,属性更加易于修改。假如,客户对象不应该有空白的名称。若使用的公有属性来封装Name,那么只需要这样简单的修改即可:

1         public class Customer 2         { 3             private string name; 4             public string Name 5             { 6                 get { return name; } 7                 set 8                 { 9                     if (string.IsNullOrEmpty(value))10                     {11                         throw new ArgumentException("不能使用空白名称", "Name");12                     }13                     name = value;14                 }15             }16         }

 

属性的多线程支持

  因为属性是通过方法来实现的,所以添加多线程支持也非常简单。只需下面的简单修改可以支持对数据的同步访问:

1         public class Customer 2         { 3             private object syncHandle = new object(); 4  5             private string name; 6             public string Name 7             { 8                 get 9                 {10                     lock (syncHandle)11                         return name;12                 }13                 set14                 {15                     if (string.IsNullOrEmpty(value))16                     {17                         throw new ArgumentException("不能使用空白名称", "Name");18                     }19                     lock (syncHandle)20                         name = value;21                 }22             }23         }

 

属性是通过方法来实现的,那么自然属性也拥有方法的所有语言特征(abstract,Interface,virtual...)

  属性可以定义为virtual的:

1   public class Customer2         {3             //C#3.0隐式属性语法(不需要验证getter或setter逻辑时)4             public virtual string Name5             {  6                 get;7                 set;8             }9         }

  

也可以将属性声明为抽象(abstract)的,以类似隐式属性语法的形式定义在接口中。接口只是定义了一个契约,强制所以实现了该接口的类型都必须满足,如下:

1  public interface INameValuePair
2 { 3 string Name 4 { 5 get; 6 } 7 8 T Value 9 {10 get;11 set;12 }13 }

 

属性的访问器将作为两个独立的方法编译到你的类型中,我们可以为属性的get和set访问器制定不同的访问权限以实现更精确的控制:

1     public class Customer2     {3         public virtual string Name4         {5             get;6             protected set;7         }8     }

 

通过属性返回序列中的项,我们可以看到List<T>类的Item属性(所有得索引器都是使用this关键字声明的):

1         public T this[int index]2         {3             get;4             set;5         }

 

 小节:

  无论何时需要在类型的公有或保护接口中暴露数据,都应该使用属性。你也应该使用索引器来暴露序列或字典。所有的数据成员都应该是私有的,没有任何例外。这样你就立即得到了数据绑定的支持,也便于日后对方法实现进行各种修改。

 

阅读书目:

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2012/08/20/Effective_CSharp_01.html
,如需转载请自行联系原作者
你可能感兴趣的文章
Angular练习之animations动画二
查看>>
mac vscode Python配置
查看>>
阿里创新自动化测试工具平台--Doom
查看>>
weex踩坑之旅第二弹 ~ 在weex中集成vue-router
查看>>
文档的加载
查看>>
在 mac 下安装 GNU 软件包
查看>>
垂直水平居中的方式总结 +(使用场景)
查看>>
比特币所有权及隐私问题-非对称加密应用
查看>>
GitChat · 管理 | 一篇文章读懂项目管理中的精髓
查看>>
GitChat · 前端 | 浅尝初试 React 技术栈
查看>>
Koa-jwt 说明文档(机翻润色)
查看>>
如何利用容器降低云成本?
查看>>
多线程中的局部变量
查看>>
React 组件渲染性能探索
查看>>
抽红包
查看>>
常用正则
查看>>
【MySQL】Mysql锁机制简介
查看>>
css3 loading
查看>>
在headless模式下运行selenium
查看>>
OpenJDK9 Hotspot :oops,klass 与 handle
查看>>