jon*_*lon 5 c# static-methods caching
我遇到过这段代码,看起来原始开发人员试图使用静态字符串来缓存静态类中的值。
public static class GetStringFromSomeProcess
{
private static string theAnswer;
public static string GetString
{
get
{
if(theAnswer == null)
{
theAnswer = GoGetTheAnswerFromALongRunningProcess();
}
return theAnswer;
}
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这是行不通的,因为您无法实例化GetStringFromSomeProcess该类,GoGetTheAnswerFromALongRunningProcess每次使用时都会被调用GetString。我错过了什么吗?
这将工作正常 - 只有一个实例,theAnswer因为它是静态的 - 并且(也因为它是静态的)它可以从公共静态属性访问。这意味着对其所做的任何更改对于访问它的所有代码都是可见的。因此第一次调用GetString将设置theAnswer为非空,后续调用将不会调用GetStringFromSomeProcess().
但是,您发布的解决方案不是线程安全的,因为GoGetTheAnswerFromALongRunningProcess()可以由多个线程同时调用。
.Net提供了Lazy解决这个问题的类,如下:
public static class GetStringFromSomeProcess
{
private static readonly Lazy<string> _theAnswer = new Lazy<string>(GoGetTheAnswerFromALongRunningProcess);
public static string GetString
{
get
{
return _theAnswer.Value;
}
}
public static string GoGetTheAnswerFromALongRunningProcess()
{
return "X";
}
}
Run Code Online (Sandbox Code Playgroud)
您向类的构造函数提供Lazy<T>一个方法,它可以在需要时调用该方法来创建它所包装的对象。在上面的示例中,我传递GoGetTheAnswerFromALongRunningProcess给它的构造函数。
另请注意,拥有需要很长时间才能归还的房产通常不是一个好主意。最好将其设为一种方法:
public static string GetString()
{
return _theAnswer.Value;
}
Run Code Online (Sandbox Code Playgroud)