创建常量、原子性的值类型
2009-03-26 08:22:16 来源:WEB开发网可以看到,尽管 phones字段声明为了readonly,并且也只提供了get属性访问器。我们仍然可以通过 Address对象a外部的变量b,修改了a对象内部的内容。如何避免这种情况的发生呢?我们可以通过深度复制的方式来解决,在Phones的get属性访问器中添加如下代码:
public string[] Phones {
get {
string[] rtn = new string[phones.Length];
phones.CopyTo(rtn, 0);
return rtn;
}
}
在Get访问器中,我们创建了一个新的数组,并将Address对象本身的数组内容进行了拷贝,然后返回给调用者。此时,再次运行刚才的代码,由于b指向了新创建的这个数组对象,而非Address对象a内部的数组对象,所以对于b的修改将不再影响到a。再次运行刚才的代码,我们可以得到 029-88401100 的输出。
但是问题还没有结束,我们再看下面这段代码:
string[] phones = { "029-88401100", "029-88500321" };
Address a = new Address("陕西", "西安", "710068", phones);
Console.WriteLine(a.Phones[0]); // 输出: 029-88401100
phones[0] = "029-XXXXXXXX"; // 通过phones变量修改了Address对象内部的数据
Console.WriteLine(a.Phones[0]); // 输出: 029-XXXXXXXX
再创建Address对象完毕,我们依然可以通过之前的数组变量来修改对象内部的数据,受到前面的启发,很容易想到我们可以在构造函数中对外部传递进来的数组进行深度复制:
public Address(string province, string city, string zip, string[] phones) {
// 前面略...
this.phones = new string[phones.Length];
phones.CopyTo(this.phones, 0);
CheckZip(zip); // 验证格式
}
这样,我们再次运行上面的代码,对于phones的修改便不会再影响到Address对象本身。
总结
这篇文章向大家讲述了类型设计时需要注意的三个问题:1、当创建类型的目的是为了存储一组相关的数据,且数据量不是很大的时候,将它声明为Struct比Class会获得更高的效率;2、将类型声明为具有原子性和常量性,可以避免可能出现的数据不一致问题;3、通过在构造函数和Get访问器中,对对象的字段进行深度复制,可以避免在类型的外部修改类型内部数据的问题。
感谢阅读,希望这篇文章能带给你帮助!
- ››创建SQL2005自动备份,定期删除的维护计划
- ››创建动态表单 javascript
- ››创建基于PPTP的站点到站点VPN连接:ISA2006系列之...
- ››创建基于L2TP的站点到站点的VPN连接:ISA2006系列...
- ››创建一个Twisted Reactor TCP服务器
- ››创建Windows Mobile上兼容性好的UI 程序
- ››创建android的Service
- ››创建远古部落环境与原住民角色
- ››创建并扩展Apache Wicket Web应用
- ››创建不在任务条中显示窗口按钮的应用
- ››创建 Android 文件系统(Root file system)
- ››创建 Android 系统步骤简介
更多精彩
赞助商链接