在C#中,最简单的初始化实例字段的方法是什么?

时间:2013-04-10 10:04:18

标签: c# asp.net class generics

我有一个5-6个字段的类,应该在构造函数运行后初始化一次。

 public OriginalFileProcessor(IConfigManager configManager)
        {
            this._configManager = configManager;
            this._field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);
            this._field2 = this._configManager.GetAppSetting<int>ConfigKeys.Key2);
            this._field3 = this._configManager.GetAppSetting<int>ConfigKeys.Key3);
            this._field4 = this._configManager.GetAppSetting<int>ConfigKeys.Key4);
            this._field5 = this._configManager.GetAppSetting<int>ConfigKeys.Key5);
        }

但我不喜欢在构造函数中仅仅编写简单的赋值来编写逻辑。

我不能对field1使用内联初始化,例如,因为那时我不能在那里使用_configManager实例:

private int readonly _field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);

如果我使用readonly属性,那么我必须添加这样的额外代码:

  private int? _field1;
        public int Property1
        {
            get
            {
                if (!this._field1.HasValue)
                {
                    this.__field1 = this._configManager.GetAppSetting<int>(Key1);    
                }
                return this._field1.Value;
            }
        }

是否有更简单的方法来进行实例字段的后期初始化?

1 个答案:

答案 0 :(得分:5)

Lazy<T>是建议的好选择。

我通常使用以下内容......

提供_field*nullable

在你的财产中你可以做...

return this.__field1 ?? (this.__field1 = this._configManager.GetAppSetting<int>(Key1));  

编辑:

鉴于评论讨论 - 为什么不使用non static approach而不是Lazy<T>,例如

private readonly Lazy<int?> _field;
// init in ctor
_field = new Lazy<int?>(() => YourFieldInit(""));
// use in property
return _field.Value ?? 0;  

编辑2:

一个小小的测试来澄清懒惰的行为:

public class DoLazy
{
    Lazy<int?> _field;
    public DoLazy()
    {
        // 'lazy' gets initialized - but `YourFieldInit` is not called yet.
        _field = new Lazy<int?>(() => YourFieldInit(""));
    }
    int Property
    {
        get
        {
            // `YourFieldInit` is called here, first time.
            return _field.Value ?? 0;
        }
    }
    int? YourFieldInit(string test)
    {   // breakpoint here
        return -1;
    }
    public static void Test()
    {
        var lazy = new DoLazy();
        int val1 = lazy.Property;
        var val = lazy.Property;
    }
}

YourFieldInit内放置一个断点 - 以查看它实际被调用的时间 从您的电话中拨打DoLazy.Test()主要。