C#惰性加载自动属性
在C#中,C#惰性加载自动属性
有没有办法将一个自动属性变成带有指定默认值的延迟加载自动属性?
从本质上讲,我试图把这个...
private string _SomeVariable
public string SomeVariable
{
get
{
if(_SomeVariable == null)
{
_SomeVariable = SomeClass.IOnlyWantToCallYouOnce();
}
return _SomeVariable;
}
}
到不同的东西,在那里我可以指定默认的,它会自动处理剩下的...
[SetUsing(SomeClass.IOnlyWantToCallYouOnce())]
public string SomeVariable {get; private set;}
不,没有。自动实现的属性仅用于实现最基本的属性:带getter和setter的后台字段。它不支持这种类型的自定义。
但是你可以使用4.0 Lazy<T>
类型来创建这个模式
private Lazy<string> _someVariable =new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable {
get { return _someVariable.Value; }
}
此代码将懒洋洋地计算_someVariable
首次Value
表达被称为价值。它只会被计算一次,并将缓存价值以供将来使用Value
属性
也许是最简洁的,你可以得到的是使用空合并运算符:
get { return _SomeVariable ?? (_SomeVariable = SomeClass.IOnlyWantToCallYouOnce()); }
在'IOnlyWantToCallYouOnce'返回'null'的情况下,它会多次调用它。 – JaredPar 2010-10-27 19:26:08
使用空合并运算符时,上述示例将失败。正确的语法是:'_SomeVariable ?? (_SomeVariable = SomeClass.IOnlyWantToCallYouOnce());' - 注意围绕设置'_SomeVariable'添加括号,如果它为空。 – 2012-10-22 16:49:51
下面是我实现的解决您的问题。基本上这个想法是一个属性,它将在第一次访问时由函数设置,随后的访问将产生与第一次访问相同的返回值。
public class LazyProperty<T>
{
bool _initialized = false;
T _result;
public T Value(Func<T> fn)
{
if (!_initialized)
{
_result = fn();
_initialized = true;
}
return _result;
}
}
然后使用:
LazyProperty<Color> _eyeColor = new LazyProperty<Color>();
public Color EyeColor
{
get
{
return _eyeColor.Value(() => SomeCPUHungryMethod());
}
}
当然还有各地的传递函数指针的开销,但它的工作,我和比我跑没有注意到的开销太大该方法一遍又一遍。
有一个在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; }
}
}
目前可以写为:
public class SomeClass
{
private Lazy<string> _someVariable = new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable => _someVariable.Value;
}
在上一节的代码,初始化实际上并不是懒惰的。在每次实例化类时,都会调用“IOnlyWantToCallYouOnce”。 – 2016-07-03 14:51:51
@TomBlodget谢谢,你是对的 – 2016-08-18 14:56:47
因此换句话说这不是懒加载? – Zapnologica 2017-01-30 08:40:39
https://github.com/bcuff/AutoLazy使用Fody到给你这样的东西
public class MyClass
{
// This would work as a method, e.g. GetSettings(), as well.
[Lazy]
public static Settings Settings
{
get
{
using (var fs = File.Open("settings.xml", FileMode.Open))
{
var serializer = new XmlSerializer(typeof(Settings));
return (Settings)serializer.Deserialize(fs);
}
}
}
[Lazy]
public static Settings GetSettingsFile(string fileName)
{
using (var fs = File.Open(fileName, FileMode.Open))
{
var serializer = new XmlSerializer(typeof(Settings));
return (Settings)serializer.Deserialize(fs);
}
}
}
@Gabe:注意,只有当它永远不会ret urns null。 – RedFilter 2010-10-27 19:25:16
我发现...它似乎是使用单例模式 – ctorx 2010-10-28 19:50:08