《Effective C#》读书笔记——条目26:避免返回对内部类对象的引用<使用C#表达设计>-阿里云开发者社区

开发者社区> 吞吞吐吐的> 正文

《Effective C#》读书笔记——条目26:避免返回对内部类对象的引用<使用C#表达设计>

简介:
+关注继续查看

  可能你会认为只读属性就只能读取,调用者不可能改变属性值。并非所有的情况都是如此,我们看下面的示例:

复制代码
 1     public class MyBusinessObject
 2     {
 3         private List<string> listOfData = new List<string> {"COM1","COM2","COM3","COM4","COM5","COM6" };
 4 
 5         public List<string> Data
 6         {
 7             get { return listOfData; }
 8         }
 9         //其他细节省略
10     }
复制代码

本来我们希望MyBusinessOjbect类的Data属性是只读的,但是现在仍然可以通过其返还的引用来改变其内部状态:

1             MyBusinessObject bo = new MyBusinessObject();
2             //访问集合
3             List<string> stuff = bo.Data;
4             //不应该这些,但是这里却允许
5             stuff.Clear();

  显然,这并不是我们希望的行为,我们为类创建了严格的接口,然后让用户通过接口使用对象。我们不希望用户在我们不知道的情况下,访问或者修改对象的内部状态。我们有四种策略可以防止这种类型的内部数据结构遭受有意或无意的修改

  • 值类型
  • 常量类型
  • 接口
  • 包装器(Wrapper)

 

1.值类型

  当客户代码通过属性来访问值类型的成员时,实际返回的是值类型的副本,而对副本的任何修改都不会影响对象的内部状态。

 

2.常量类型

   常量类型也是安全的(参见:Effective C# 笔记条目20)。我们可以在类型中安全地返回字符串或者其他的常量类型,客户代码不可能对它们做出任何更改,因为我们也可以保证类型内部状态的安全。

 

3.定义接口

   通过定义接口,将客户对内部数据成员的访问权限限制在一部分功能中(参见:Effective C# 笔记条目22)。当我们创建类时,可以创建一组接口来支持类功能的子集。通过接口向外界暴露类的功能,即可尽量地避免内部数据遭到有意或无意的更改。使用IEnumerable接口向外提供List<T>的功能就是这种策略的一个应用。

 

4.提供包装器对象

  提供一个包装器对象,仅暴露该包装器,从而限制对其中对象的访问。System.Collections.ObjectModel.ReadOnlyCollection<T>类型就是对集合的一个标准的只读封装,让其中的数据保持只读:

复制代码
 1     public class MyBusinessObject
 2     {
 3         private List<string> listOfData = new List<string> {"COM1","COM2","COM3","COM4","COM5","COM6" };
 4 
 5         public List<string> Data
 6         {
 7             get { return listOfData; }
 8         }
 9 
10         public ReadOnlyCollection<string> CollectionOfData
11         {
12             get { return new ReadOnlyCollection<string>(listOfData); }
13         }
14         //其他细节省略
15     }
复制代码

 

小节

如果将引用类型通过公有借口暴露给外界,那么对象的使用者即可绕过我们定义的方法和属性来更改对象的内部结构。这违反了我们通常的直觉,也会导致常见的错误。考虑到这一点,你应该修改类暴露出的接口。如果只是简单的返回内部数据,那么实际上就给外界赋予了访问内部成员的权限。客户代码可以调用成员中任何可用的方法。通过使用接口、包装器对象或值类型向外部提供私有数据,即可限制外界对这些数据的访问能力。

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2013/01/19/EffectiveCSharp_26.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用常对象——为共用数据加装一个名为const的玻璃罩
原创案例讲解——”玻璃罩const”系列的三篇文章: 1. 使用常对象——为共用数据加装一个名为const的玻璃罩 2. 常(const)+ 对象 + 指针:玻璃罩到底保护哪一个 3. 对象更有用的玻璃罩——常引用   话题的引入:C++采取了不少有效的措施(如设private保护)以增加数据的安全性,但也可以在不同的场合通过不同的途径访问同一个数据对象。有时在无意之中的误操作
927 0
微服务架构(Microservice Architect Pattern)综述——什么是微服务架构(读书笔记)
简单定义:      微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调,相互配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制相互沟通(通常是基于HTTP的RESTFul API),每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境,类生成环境等。
2506 0
Effective C++ 笔记(2):尽量以const,enum,inline替换#define
条款二(clause 2) 尽量使用const,enum,inline替换#define(以编译器替换预处理器) 1、使用const替换#define 通常替换 #define NUM 3.
819 0
java之路,基础知识----内部类
内部类:在类的内部定义另一个类,方便访问外部类的所有的成员。内部类可以嵌套,但是如果定义在方法之内,那么他的作用域就在方法中,出了方法就不能使用了。必须先产生外部类对象,然后产生内部类对象 class out {     private int index = 100;   ...
595 0
使用ADO对象添加、修改、删除数据
使用ADO对象对数据库中的数据进行添加、修改和删除等操作。首先创建一个ADO类,通过ADO类连接数据库,并打开记录集。例如,使用ADO对象添加、修改、删除数据,程序设计步骤如下:(1)创建一个基于对话框的应用程序,将对话框的Caption属性修改“使用ADO对象添加、修改、删除数据”。
803 0
Effective C++ 笔记(1):视C++为语言联邦
条款一(clause 1) 将C++视为语言联邦:提出了一种将C++分为四种不同次语言的观念,四种次语言分别是: 1、C语言,面向过程的语言,C++完全向下兼容C,在C++中单纯使用C语言的语法除了遵守的一些规则...
1445 0
实例:使用纹理对象创建Sprite对象
<p><span style="font-size:14px;">精灵类是Sprite,它的类图如下图所示:</span></p> <p style="text-align: center;"><span style="font-size:14px;"><img src="http://img.blog.csdn.net/20140516181640234" alt=""><br></span
1222 0
Spring Security笔记:使用BCrypt算法加密存储登录密码
在前一节使用数据库进行用户认证(form login using database)里,我们学习了如何把“登录帐号、密码”存储在db中,但是密码都是明文存储的,显然不太讲究。这一节将学习如何使用spring security3新加入的bcrypt算法,将登录加密存储到db中,并正常通过验证。
1626 0
Java基础-10总结形式参数,包,修饰符,内部类
你需要的是什么,直接评论留言。 获取更多资源加微信公众号“Java帮帮” (是公众号,不是微信好友哦) 还有“Java帮帮”今日头条号,技术文章与新闻,每日更新,欢迎阅读 学习交流请加Java帮帮交流QQ群553841695 分享是一种美德,分享更快乐! 类,抽象类,接口的综合小练习 /* 教练和运动员案例(学生分析然后讲解
1141 0
4852
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载