cto*_*orx 93 c# automatic-properties
在C#中,
有没有办法将自动属性转换为具有指定默认值的延迟加载自动属性?
基本上,我试图扭转这个......
private string _SomeVariable
public string SomeVariable
{
get
{
if(_SomeVariable == null)
{
_SomeVariable = SomeClass.IOnlyWantToCallYouOnce();
}
return _SomeVariable;
}
}
Run Code Online (Sandbox Code Playgroud)
到不同的东西,我可以指定默认值,它自动处理其余的...
[SetUsing(SomeClass.IOnlyWantToCallYouOnce())]
public string SomeVariable {get; private set;}
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 105
不,那里没有.自动实现的属性仅用于实现最基本的属性:带有getter和setter的后备字段.它不支持这种类型的自定义.
但是,您可以使用4.0 Lazy<T>
类型来创建此模式
private Lazy<string> _someVariable =new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable => _someVariable.Value;
Run Code Online (Sandbox Code Playgroud)
此代码将懒惰地计算_someVariable
第一次Value
调用表达式时的值.它只会被计算一次,并将缓存该值以供将来使用该Value
属性
Gab*_*art 34
您可以获得的最简洁的可能是使用null-coalescing运算符:
get { return _SomeVariable ?? (_SomeVariable = SomeClass.IOnlyWantToCallYouOnce()); }
Run Code Online (Sandbox Code Playgroud)
Ale*_*rck 14
C#6中有一个名为Expression Bodied Auto-Properties的新功能,它允许你把它写得更清洁:
public class SomeClass
{
private Lazy<string> _someVariable = new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable
{
get { return _someVariable.Value; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以写成:
public class SomeClass
{
private Lazy<string> _someVariable = new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable => _someVariable.Value;
}
Run Code Online (Sandbox Code Playgroud)
cap*_*p29 11
运算符??=在 C# 8.0 及更高版本中可用,因此您现在可以更简洁地使用它:
private string _someVariable;
public string SomeVariable => _someVariable ??= SomeClass.IOnlyWantToCallYouOnce();
Run Code Online (Sandbox Code Playgroud)
这是我对你的问题的解决方案.基本上,这个想法是一个属性,它将在第一次访问时由函数设置,后续访问将产生与第一个相同的返回值.
public class LazyProperty<T>
{
bool _initialized = false;
T _result;
public T Value(Func<T> fn)
{
if (!_initialized)
{
_result = fn();
_initialized = true;
}
return _result;
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用:
LazyProperty<Color> _eyeColor = new LazyProperty<Color>();
public Color EyeColor
{
get
{
return _eyeColor.Value(() => SomeCPUHungryMethod());
}
}
Run Code Online (Sandbox Code Playgroud)
当然有传递函数指针的开销,但是它为我完成了工作,而且与一遍又一遍地运行方法相比,我没有注意到太多的开销.