WEB开发网
开发学院软件开发C语言 创建常量、原子性的值类型 阅读

创建常量、原子性的值类型

 2009-03-26 08:22:16 来源:WEB开发网   
核心提示: 可以看到,尽管 phones字段声明为了readonly,创建常量、原子性的值类型(5),并且也只提供了get属性访问器,我们仍然可以通过 Address对象a外部的变量b,对对象的字段进行深度复制,可以避免在类型的外部修改类型内部数据的问题,修改了a对象内部的内容,如何避免这种情况的发生

可以看到,尽管 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访问器中,对对象的字段进行深度复制,可以避免在类型的外部修改类型内部数据的问题。

感谢阅读,希望这篇文章能带给你帮助!

上一页  1 2 3 4 5 

Tags:创建 常量 原子

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接