2011-03-18 269 views
23

A)在下面的代碼中,方法DataTools.LoadSearchList()只會被調用一次,或每次訪問屬性時?靜態屬性初始化

public static IEnumerable<string> SearchWordList 
{ 
    get 
    { 
     return DataTools.LoadSearchList(); 
    } 
} 

B)這有什麼區別嗎?

public static IEnumerable<string> SearchWordList = DataTools.LoadSearchList(); 
+4

屬性和字段的行爲完全不同,儘管從編碼的角度看它們可能看起來很相似。一個屬性實際上只是一對獲取/設置方法的快捷方式,並且與任何方法一樣,每次調用時都會執行該正文。 – MattDavey 2011-03-18 15:25:14

回答

29

在第一個示例中,每次訪問屬性時都會調用LoadSearchList()。

第二,LoadSearchList()只會被調用一次(但它將被調用,無論您是否使用它,因爲它現在是一個字段而不是屬性)。

一個更好的選擇可能是:

private static IEnumerable<string> _searchWordList; 

public static IEnumerable<string> SearchWordList 
{ 
    get 
    { 
     return _searchWordList ?? 
      (_searchWordList = DataTools.LoadSearchList()); 
    } 
} 

或者,如果你使用.NET 4.0和想要的東西線程安全的,你可以使用Lazy<T>,如喬恩斯基特提到(我覺得語法應該是正確的,但不要抱着我):

private static Lazy<IEnumerable<string>> _searchWordList = 
    new Lazy<IEnumerable<string>>(() => DataTools.LoadSearchList()); 

public static IEnumerable<string> SearchWordList 
{ 
    get { return _searchWordList.Value; } 
} 
+3

請注意,如果有多個屬性,它可能會被多次調用涉及的線程。我個人更喜歡使用.NET 4中的'懶惰',如果這是一個選項。然後很容易調整這種事情來創建第二個併發的調用者塊,例如。 – 2011-03-18 15:34:15

+0

@Jon Skeet - 更新了一個例子...希望我的語法正確。 – 2011-03-18 15:39:21

+2

對我來說看起來不錯,儘管我認爲*你可能只是使用'new Lazy >(DataTools.LoadSearchList)'來使用方法組轉換。 – 2011-03-18 15:48:25

12

在第一種情況下,每次訪問屬性時都會調用該方法。當它被設置爲一個字段時,它將只運行一次 - 當它初始化的類型 - 是否有有史以來訪問。

如果你想有一個延遲初始化值,我建議你從Lazy<T> .NET 4

2

是,酒店將調用DataTools.LoadSearchList()每次訪問。靜態字段只會調用一次該方法。