2011-04-05 11 views
5

que tiene una propiedad de clase que se ve de la siguiente manera:C# - Análisis de código 2227 Confusión

public List<Recipe> RecipeList 
{ 
    get { return this._recipeList; } 

    set 
    { 
     this._recipeList = value; 
     OnPropertyChanged("RecipeList"); 
    } 
} 

En otro método Tengo el siguiente que hace referencia a la propiedad anterior.

private void RecipeSearch() 
{ 
      this.RecipeList = RecipeManagerService.SearchByUnit(SearchCriteria) 
           .Where(recipe => recipe.IsApproved == true && !recipe.IsHidden).ToList(); 
} 

análisis de código es la emisión de una advertencia CA 2227: Cambio RecipeList a ser de sólo lectura mediante la eliminación de la incubadora. ¿Alguien podría decirme por qué?

+0

¿Hay algo que use el setter? – Douglas

+0

@Douglas - Sí, tengo XAML vinculado a ella. – Hosea146

Respuesta

3

Agregar un setter público en un objeto List<T> es peligroso. Puede eliminar esta advertencia al hacer que su setter privado:

public List<Recipe> RecipeList 
{ 
    get { return this._recipeList; } 

    private set 
    { 
     this._recipeList = value; 
     OnPropertyChanged("RecipeList"); 
    } 
} 

Esto todavía le permitirá a su clase para cambiar este método, pero ninguna fuente externa.

+0

Gracias. Esto es exactamente lo que debería hacer. – Hosea146

1

¿Desea otra instancia jugando con RecipeList? En general, no dejo que nada cambie las instancias de mi colección, excepto la instancia que posee la colección. Puede hacerlo private.

2

Creo que está sugiriendo que, por lo general, las propiedades de la colección no deberían ser mutables; es más común que la colección sea mutable y solo esté disponible a través de un setter.

Es sólo una sugerencia, aunque :)

En este caso se usaría:

RecipeList.Clear(); 
RecipeList.AddRange(RecipeManagerService 
           .SearchByUnit(SearchCriteria) 
           .Where(r => r.IsApproved && !r.IsHidden)); 

Tenga en cuenta que esta no será fuego el evento de cambio ... aunque es posible que desee use ObservableCollection en su lugar.

Esto también significa que cualquier persona puede cambiar el contenido de la lista de recetas ... ¿definitivamente quiere eso? Otra alternativa es exponer una propiedad ReadOnlyCollection<T> o algo así, y solo realizar cambios dentro de su propia clase. Sin embargo, realmente depende de lo que estés tratando de hacer.

0

No creo que haya nada ilegal sobre el código, pero es una práctica común no tener un organismo público para las propiedades del tipo de colección. Su método privado RecipeSearch debería simplemente establecer _recipeList y plantear el evento, o podría hacer que _recipeList sea una propiedad protegida que maneja el evento.

1

El MSDN description es bastante claro:

Una propiedad de colección escritura permite un usuario para reemplazar la colección con una colección completamente diferente

No sería bueno si el cliente OO de su clase podría cambiar la lista para que sea una lista completamente diferente de Recetas. Eso está en contra de encapsulation.

Garantizar que los clientes solo agreguen o eliminen elementos es lo que probablemente quiera hacer.

0

Permitir la propiedad lista para ser mutado de dos maneras (a través de él es poseer métodos y AddRemove y la instancia de la lista en su conjunto) crea una interfaz ambigua a los que consumen esa propiedad. Esto confunde las responsabilidades y crea una sobrecarga técnica/de mantenimiento más grande.

En su lugar, a menudo es mejor separar estas preocupaciones para que la propiedad proporcione acceso a una sola instancia de la lista. Si la instancia de la lista debe ser modificable, un mecanismo separado para hacerlo deja mucho más claro que la acción de interactuar con la propiedad y la acción de cambiar a qué instancia de lista apunta esa propiedad son distintas.