我正在寻找是否有优雅的方法来确保第一次访问属性时,设置了相关的后备字段。例如,我最终使用下面的代码范例来解决这个问题:
private Address _address;
public Address Address
{
get
{
if (_address == null)
{
_address = GetAddress();
}return _address;
}
}
答案 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();
}