代码之家  ›  专栏  ›  技术社区  ›  rahulaga-msft

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

  •  2
  • rahulaga-msft  · 技术社区  · 7 年前

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

    private Address _address;
            public Address Address
            {
                get
                {
                    if (_address == null)
                    {
                        _address = GetAddress();
                    }return _address;
                }
            }  
    
    3 回复  |  直到 7 年前
        1
  •  5
  •   Zohar Peled    7 年前

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

    public class MyClass
    {
        private Address _address;
    
        public MyClass()
        {
            _address = GetAddress();
        }
    
        public Address Address {get {return _address;}}
    }
    

    使用 懒惰(<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.

        2
  •  2
  •   Steve Harris    7 年前

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

    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;
    
        3
  •  0
  •   Ipsit Gaur    7 年前

    在构造函数本身中指定属性值,如下所示

    private Address _address;
    public Address Address
    {
      get { return _address; }
    }
    
    public ABC() //Constructor 
    {
      _address = GetAddress();
    }