2011-03-18 238 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()每次访问。静态字段只会调用一次该方法。