65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的不可变对象

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.61/5 (23投票s)

2015年10月26日

CPOL

3分钟阅读

viewsIcon

98820

在本文中,我们将解释 C# 中的不可变性。

目录

引言

有句谚语说“趁泥湿时制陶”。 一旦泥变干,就无法改变。 不可变对象也遵循类似的原则。 一旦创建了对象,就无法以任何方式修改它。

什么是不可变对象?

不可变对象是指一旦加载就无法以任何外部或内部方式更改/修改的对象。

不可变对象在哪里使用?

如果用一句话概括,不可变对象用于静态数据。 以下是一些示例:

  • 主数据:不可变对象最大的用途之一是加载主数据。 像国家、货币、地区等主数据很少更改。 所以我们希望将主数据加载到内存中一次,然后我们不希望它被修改。
  • 配置数据:所有应用程序都需要配置数据。 在 Microsoft 世界中,我们通常将这些配置数据存储到 *Web.config* 或 *App.config* 文件中。 这种数据由对象表示,一旦加载到应用程序内存中,这些数据就不会更改。 将这些配置数据对象设置为不可变对象也是一个好习惯。
  • 单例对象:在应用程序中,我们通常为共享静态数据创建单例对象。 因此,如果共享数据没有改变,那么它就是不可变对象的绝佳选择。 如果您不熟悉单例模式,请参考本文 C# 中的单例模式

我们如何在 C# 中创建不可变对象?

不可变对象只能从不可变类创建。 创建不可变类是一个三步过程

步骤 1:删除类的 setter,只保留 getter。
创建不可变类的第一步是删除 setter。 正如我们所说,不可变类的值不能从外部或内部修改。 因此,通过删除 getter,任何创建此类对象的客户端都无法在加载数据后修改数据。

class Currency
{
        private string _CurrencyName;
        public string CurrencyName
        {
            get { return _CurrencyName; }
        }
        private string _CountryName;
        public string CountryName
        {
            get { return _CountryName; }
        }        
}

步骤 2:通过构造函数提供参数。

我们删除了 getter,因此无法将数据加载到类中。 因此,为了提供数据,我们需要创建带有参数的构造函数,通过这些参数我们可以将数据传递给对象。 以下是修改后的代码。

class Currency
{
// property Code removed for clarity

        public Currency(string paramCurrencyName,
                        string paramCountryName)
        {
            _CurrencyName = paramCurrencyName;
            _CountryName = paramCountryName;
        }
}

步骤 3:将属性的变量设为 READONLY

正如我们在之前的定义中所说,一旦加载数据,就不能以任何方式修改不可变对象。 我会更进一步说,客户端不能从外部修改它,类代码本身也不能从内部修改它。

但是如果你看到我们的 currency 类,变量可以在对象创建后被修改。 换句话说,请参阅下面的类代码。 我们在类中创建了一个名为“SomeLogic”的方法。 在对象创建后,此方法能够成功修改变量。

class Currency
{
        private string _CountryName;

        public string CountryName
        {
            get { return _CountryName; }
        }

        public void SomeLogic()
        {
            _CountryName = "I can not change this";
        }
}

因此,上述的解决方案是将变量设为“READONLY”。 以下是修改后的 currency 类,其中属性变量被设为 readonlyReadonly 变量只能在构造函数中初始化,之后就无法修改。

class Currency
    {
        private readonly string _CurrencyName;

        public string CurrencyName
        {
            get { return _CurrencyName; }
        }
        private readonly string _CountryName;

        public string CountryName
        {
            get { return _CountryName; }
        }
        public Currency(string paramCurrencyName,
                        string paramCountryName)
        {
            _CurrencyName = paramCurrencyName;
            _CountryName = paramCountryName;
        }
    }

希望您喜欢这篇关于不可变对象的短文。 不可变对象是一种设计模式,它最早在《Java 并发实践》一书中被正式讨论。 如果您有兴趣学习设计模式,我建议创建一个完整的项目并开始在其中实现设计模式。

进一步阅读,请观看下面的面试准备视频和分步视频系列。

© . All rights reserved.