utiliza que publicas protegidas privados privadas para niveles encapsulamiento clases atributos ambito c# wpf mvvm c#-6.0

c# - publicas - para que se utiliza public



Propiedad con acomodador privado versus propiedad de solo-obtener (3)

Aquí es en lo que sus propiedades se convierten después de que el compilador hizo la tarea por usted:


1. public ICommand AddCommand { get; } public ICommand AddCommand { get; } :

private readonly ICommand <AddCommand>k__BackingField; public ICommand AddCommand { get { return this.<AddCommand>k__BackingField; } }


2. private List<Screenshot> Screenshots { get; set; } private List<Screenshot> Screenshots { get; set; } private List<Screenshot> Screenshots { get; set; } :

private List<Screenshot> <Screenshots>k__BackingField; private List<Screenshot> Screenshots { get { return this.<Screenshots>k__BackingField; } set { this.<Screenshots>k__BackingField = value; } }


3. public ICommand AddCommand { get; private set; } public ICommand AddCommand { get; private set; } public ICommand AddCommand { get; private set; } :

private ICommand <AddCommand>k__BackingField; public ICommand AddCommand { get { return this.<AddCommand>k__BackingField; } private set { this.<AddCommand>k__BackingField = value; } }

En resumen, la propiedad pública de obtención solo se puede asignar en el constructor (porque el campo es de solo lectura) o por esta nueva sintaxis:

public ICommand AddCommand { get; } = new MyCommand();

pero al igual que con cualquier otro campo de solo lectura, este código se coloca de todos modos en el constructor, por lo que no hay una gran diferencia:

public MyClass1() { this.<AddCommand>k__BackingField = new MyCommand(); }

C # 6.0 introduce la capacidad de definir propiedades de solo obtención:

public ICommand AddCommand { get; }

Ahora, cuando se define otra propiedad como la siguiente, ReSharper sugiere que Auto-propiedad se puede hacer solo para obtener :

private List<Screenshot> Screenshots { get; set; }

Además, ReSharper no dice nada al definir captadores privados:

public ICommand AddCommand { get; private set; }

¿Cuál es la diferencia entre una propiedad pública de obtención solo (como el primer AddCommand ), una propiedad privada de obtención solo (como la propiedad Screenshots ) y la propiedad pública privada (como el segundo AddCommand )?

A mi aplicación WPF no parece importar si su propiedad pública (UICommand) contiene un setter privado o ningún setter, ¿pero seguramente debe haber una diferencia?


En este caso específico de comandos de enlace, realmente no importa.

En otros casos, es decir, tener una clase que recibe un servicio inyectado a través del constructor y desea exponerlo (por cualquier motivo), es importante usar propiedades de solo lectura.

Por ejemplo:

public class MainViewModel { public INavigationService NavigationService { get; } public MainViewModel(INavigationService navigationService) { if(navigationService == null) throw new ArgumentNullException(navigationServie); NavigationService = navigationService; } }

Al usar esto, garantiza esta clase de invariantes y garantiza que NavigationService nunca será null , por lo que no es necesario que realice comprobaciones nulas contra NavigationService antes de usarlo. Una vez que deja el constructor, no se puede cambiar (bueno, excepto a través de la reflexión).

Por otro lado si tienes

public class MainViewModel { public INavigationService NavigationService { get; private set; } public MainViewModel(INavigationService navigationService) { if(navigationService == null) throw new ArgumentNullException(navigationServie); NavigationService = navigationService; } }

luego es posible escribir código (por error o por un desarrollador inexperto) que hace NavigationService = null y luego, si no tiene controles nulos y accede a él, obtendrá una NullReferenceException y, si no se maneja, su aplicación falla.

Volviendo a su ejemplo: en el caso de ICommand ... por lo general, no accede a los Comandos dentro de su ViewModel, solo asígnele (generalmente en el constructor o cuando cambia el contenido de su modelo de vista, como un modelo de vista secundario que usted desea asignar. es el comando a la propiedad del comando de viewmodel principal).

En caso de una lista:

Si nunca hace Screenshots = new List<ScreenShot>() o Screenshots = DisplayScreenshots() en su código y solo lo inicializa en el constructor, entonces es mejor hacer que se lea solo por la misma razón: entonces puede garantizar que Screenshots nunca es nulo y no tendrá que escribir código como

if(Screenshots != null) { Screenshots.Add(new Screenshot(...)); }

o

if(Screenshot == null) { Screenshots = new List<Screenshot>(); } Screenshots.Add(new Screenshot(...));

de nuevo y en su lugar siempre use

Screenshots.Add(new Screenshot(...));

Esto tiene una gran ventaja de que necesita menos código, su código es más legible y más fácil de mantener, ya que no puede "olvidar" una comprobación nula y arriesgarse a una NullReferenceException .

Espero que se aclare.


Respuesta corta:

public ICommand AddCommand { get; }

estará respaldado por un campo de readonly y ningún código de C # podrá cambiarlo más allá de la ejecución de los constructores.

Además, el compilador generará un código para asignar directamente el respaldo archivado, ya que no hay un acceso a la propiedad.

Por otra parte:

public ICommand AddCommand { get; private set; }

estará respaldado por un campo no de readonly y puede ser asignado en cualquier momento por cualquier código con acceso a miembros privados.

En este caso, el compilador generará un código de configuración de propiedad normal.

Para el mundo exterior, un setter privado es como si no existiera. Entonces, es lo mismo que si realmente no existiera.