首次访问 属性 且支持字段成员为空时的编码风格
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;
我正在寻找是否有优雅的方法来确保在第一次访问 属性 时设置关联的支持字段。例如,我最终使用以下代码范例来解决这个问题:
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;