2011-03-18 20 views
23

A) En el siguiente código, ¿solo se llamará al método DataTools.LoadSearchList() una vez, o cada vez que se accede a la propiedad?inicialización de propiedad estática

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

B) ¿Hay alguna diferencia en esto?

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

Las propiedades y los campos se comportan de forma completamente diferente, aunque pueden parecer similares desde un punto de vista de codificación. Una propiedad es en realidad solo un acceso directo para un par de métodos get/set, y como cualquier método, el cuerpo se ejecutará cada vez que lo llame. – MattDavey

Respuesta

29

En su primer ejemplo, se llamará a LoadSearchList() cada vez que se accede a la propiedad.

En el segundo, LoadSearchList() solo se llamará una vez (pero se llamará si lo usa o no, ya que ahora es un campo en lugar de una propiedad).

Una mejor opción podría ser:

private static IEnumerable<string> _searchWordList; 

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

O si está utilizando .NET 4.0 y quieren algo seguro para subprocesos se puede utilizar Lazy<T>, como se mencionó Jon Skeet (creo que la sintaxis debe ser correcta, pero no me retiene):

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

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

Tenga en cuenta que * podría * llamarse más de una vez, si hay múltiples hilos involucrados. Personalmente, prefiero usar 'Lazy ' de .NET 4, si esa es una opción. Entonces es fácil ajustar este tipo de cosas para hacer el segundo bloqueo de llamadas concurrente, por ejemplo. –

+0

@Jon Skeet - Actualizado con un ejemplo ... espero tener la sintaxis correcta. –

+2

Me parece bien, aunque * creo que * probablemente podría hacer 'nuevo Lazy > (DataTools.LoadSearchList)' para usar una conversión de grupo de métodos. –

12

En el primer caso, se llamará al método cada vez que se accede a la propiedad. Cuando se configura como un campo, se ejecutará exactamente una vez, cuando se inicialice el tipo, se haya o no alguna vez accedido.

Si desea un valor inicializado con pereza-, me gustaría recomendar Lazy<T> de .NET 4.

2

Sí, la propiedad llamará DataTools.LoadSearchList() todos los accesos tiempo. El campo estático solo llamará al método una vez.

Cuestiones relacionadas