第一次访问属性时的编码样式,后备字段成员为空

时间:2018-03-13 08:51:54

标签: c# coding-style readability

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

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

3 个答案:

答案 0 :(得分:5)

除非容易出错或耗时,否则我建议在构造函数中填充属性。否则,为了线程安全,我建议使用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开始,您可以拥有这样的自动实现的属性,但是您必须使用GetAddress()方法static

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

这将转化为我所展示的第一个选项 - See SharpLab demo.

答案 1 :(得分:2)

您可以使用一种简单的方法稍微干掉属性代码:

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;

答案 2 :(得分:0)

在构造函数本身中分配属性值,如此

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

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