[英]Can a static member variable be used to cache a value in a static class?
我遇到過這段代碼,看起來原始開發人員試圖使用靜態字符串來緩存靜態類中的值。
public static class GetStringFromSomeProcess
{
private static string theAnswer;
public static string GetString
{
get
{
if(theAnswer == null)
{
theAnswer = GoGetTheAnswerFromALongRunningProcess();
}
return theAnswer;
}
}
}
據我所知,這不起作用,因為你無法實例化GetStringFromSomeProcess
類,每次使用GetString
都會調用GoGetTheAnswerFromALongRunningProcess
。 我錯過了什么嗎?
你說的是無法實例化類,但是該類將存在於應用程序中。
因此,只有第一次訪問屬性時,才會調用GetStringFromSomeProcess
方法。 在此之后的每隔一段時間,檢查== null
將解析為false
並返回第一次調用評估的值。
這樣可以正常工作 - 只有一個theAnswer
實例,因為它是靜態的 - 並且(因為它是靜態的)它可以從公共靜態屬性訪問。 這意味着對其進行的任何更改都將對訪問它的所有代碼可見。 因此,第一次調用GetString
會將theAnswer
設置為非null,后續調用將不會調用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";
}
}
您向Lazy<T>
類的構造函數提供了一個方法,它可以在需要時調用它以創建它正在包裝的對象。 在上面的示例中,我將GoGetTheAnswerFromALongRunningProcess
傳遞給其構造函數。
另請注意,擁有一個可能需要很長時間才能返回的屬性通常是一個壞主意。 最好把它變成一個方法:
public static string GetString()
{
return _theAnswer.Value;
}
沒有創建GetStringFromSomeProces類的對象,它是否正常工作? 由於字符串theAnswer也是靜態的,它可能有效,但我想知道該變量何時初始化。 通常,您會像使用GetStringFromSomeProcess類的初始化建議一樣對其進行編碼。
Main.cs
...
GetStringFromSomeProcess getString = new GetStringFromSomeProcess();
string answer = getString.theAnswer();
...
GetStringFromSomeProcess.cs
public class GetStringFromSomeProcess
{
private string _theAnswer;
public string theAnswer
{
get
{
if(theAnswer == null)
{
GoGetTheAnswerFromALongRunningProcess getAnswer = new GoGetTheAnswerFromALongRunningProcess();
_theAnswer = getAnswer.GetAnswer();
}
return _theAnswer;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.