首次访问 属性 且支持字段成员为空时的编码风格

coding style while accessing property for the first time and backing field member is null

我正在寻找是否有优雅的方法来确保在第一次访问 属性 时设置关联的支持字段。例如,我最终使用以下代码范例来解决这个问题:

private Address _address;
        public Address Address
        {
            get
            {
                if (_address == null)
                {
                    _address = GetAddress();
                }return _address;
            }
        }  

在构造函数本身中分配 属性 值,就像这样

private Address _address;
public Address Address
{
  get { return _address; }
}

public ABC() //Constructor 
{
  _address = GetAddress();
}

除非容易出错或耗时,否则我建议在构造函数中填充 属性。否则,为了线程安全,我建议使用 Lazy<T> 来做:

public class MyClass
{
    private Address _address;

    public MyClass()
    {
        _address = GetAddress();
    }

    public Address Address {get {return _address;}}
}

使用Lazy<T>

public class MyClass
{
    private Lazy<Address> _address;

    public MyClass()
    {
        _address = new Lazy<Address>(() => GetAddress());
    }

    public Address Address {get {return _address.Value;}}
}

从c#6开始,你可以有这样的auto-implemented 属性,但是你必须制作GetAddress()方法static:

public Address Addgress {get;} = GetAddress();

这将转化为类似于我显示的第一个选项的内容 - See SharpLab demo.

您可以使用一种简单的方法来 DRY 一下 属性 代码:

private T GetInstance<T>(ref T instance, Func<T> getInstance)
{
    if (instance == null)
        instance = getInstance();
    return instance;
}

private Address _address;
public Address Address => GetInstance<Address>(ref _address, () => GetAddress());

private string _name;
public string Name => GetInstance<string>(ref _name, () => GetName());

编辑:在查看@Zohar 在评论中友善指出的文章后,我希望使用 Lazy 是一种更好的方法,因为您可以获得具有良好性能的线程安全性。因此,为了使其看起来尽可能整洁(IMO),可以这样做:

private readonly Lazy<Address> _address = new Lazy<Address>(() => GetAddress());
public Address Address => _address.Value;