2009-11-09 17 views
5

En Visual Studio 2008 Team System, acabo de ejecutar Code Analysis (del menú Analizar) en uno de mis proyectos de C#. Una de las advertencias producidas fue el siguiente:C# campo protegido a privado, agregar propiedad, ¿por qué?

Microsoft.Design: Debido a que el campo 'Connection._domain' es visible fuera de su tipo que se declara, cambiar su accesibilidad a privada y añadir una propiedad, con la accesibilidad mismo que el campo tiene actualmente, para proporcionar acceso a ella.

Se hace referencia a la siguiente campo:

public abstract class Connection 
{ 
    protected string _domain; 
} 

No entiendo el razonamiento detrás de la sugerencia. Esto es lo que creo que quiere que haga:

public abstract class Connection 
{ 
    private string _domain; 
    protected string Domain { get { return _domain; } set { _domain = value; } } 
} 

Dos preguntas:

  1. ¿He entendido bien lo que la sugerencia quiere que haga, código-sabio?
  2. ¿Por qué quiere que haga esto?
+0

Vea también http://stackoverflow.com/questions/1410645/are-public-fields-ever-ok, http://stackoverflow.com/questions/480627/why-wont-anyone-accept-public-fields -in-c, http://stackoverflow.com/questions/1277572/should-i-use-public-properties-and-private-fields-or-public-fields-for-data y muchas más (busque en 'public campos'). Todos hablan de los campos públicos, pero generalmente también se aplican a los campos protegidos. –

Respuesta

13

Sí, creo entendido bien - aunque en versiones posteriores de C#, hay una manera más concisa para escribirlo:

public string Domain { get; set; } 

¿Por qué? Se trata de la encapsulación. Si hace lo que sugiere, más tarde puede cambiar la definición de la propiedad de dominio sin afectar ningún código de llamada que use esa propiedad. Dado que su clase es pública, y posiblemente podría ser llamada por código que usted no escribió, eso es potencialmente muy importante.

+0

en su caso, 'dominio de cadena protegida {get; conjunto; } ' – nawfal

2

Sip. Esa es la sugerencia. No debería tener ningún acceso más alto que los campos privados expuestos como campos de instancia directa.

Es uno de los principios fundamentales de OOD - encapsulación también se refiere como 'técnica de ocultación'.

2
  1. Sí, corrigió el código del problema.
  2. Se trata de la encapsulación. _domain son datos sobre su objeto. En lugar de exponerlo directamente para que cualquier cliente tenga acceso no filtrado, debe proporcionar una interfaz para que pueda acceder a él. Prácticamente, esto podría estar agregando validación al colocador para que no se pueda establecer en ningún valor. Puede parecer tonto si eres el único código de escritura porque sabes cómo funciona tu API. Pero trate de pensar sobre las cosas en un nivel de empresa grande, es mejor tener una API para que su objeto se pueda ver como un cuadro que complementa una tarea. Puede decir que nunca tendrá la necesidad de agregar algo como validación a ese objeto, pero las cosas se hacen de esa manera para mantener la posibilidad de que así sea, y también para ser coherente.
2

Esto es porque si alguna vez quisiste cambiar el campo a una propiedad en el futuro, romperías cualquier otro ensamblaje que dependa de él.

Es una buena práctica mantener todos los campos privados y envolverlos en propiedades para que tenga la opción de agregar validación u otra lógica en el futuro sin recompilar todos los consumidores (o en este caso herederos) de su clase.

+0

¿Por qué el voto a favor? Técnicamente esto es verdad. El IL para acceder a un campo es diferente de cuando se accede a un campo. Si compila un ensamblado (A) que hace referencia a los campos en un ensamblaje diferente (B), luego actualiza el ensamblaje (B) y cambia los campos a propiedades, el ensamblaje (A) se romperá. – Bob

+0

Estoy de acuerdo, Bob, creo que esta es una consideración muy importante. (+1) Cambiar un campo a una propiedad (porque desea agregar lógica de validación o registro o desea hacerlo virtual, o cualquier otra razón que pueda existir) es un cambio binario de interrupción para cualquier usuario de la clase. También es probable que sea un salto de nivel de fuente si nombra sus campos en minúscula y las propiedades en mayúsculas, como es la convención. – Joren

+0

Y esa es la razón por la que debería usar propiedades. Si no fuera el caso, no habría ninguna razón para usar las propiedades hasta que haya decidido que las necesita. Pensé que había respondido la pregunta/encogimiento de hombros :) – GraemeF

2

Tu traducción es correcta.Se puede hacer el mismo argumento para usar propiedades 'protegidas' que las que se pueden hacer para usar propiedades 'públicas' en lugar de exponer las variables miembro directamente.

Si esto solo lleva a una proliferación de getters y setters simples, entonces creo que el daño a la legibilidad del código es mayor que el beneficio de poder cambiar el código en el futuro. Con el desarrollo de propiedades generados por el compilador de C# esto no es tan malo, sólo tiene que utilizar:

protected string Domain { get; set; } 
0

En respuesta a su pregunta ... sí.

Sin embargo, yo sólo tiene que utilizar la sintaxis de auto-propiedad:

public abstract class Connection 
{ 
    protected string Domain { get; set; } 
} 
0

Básicamente, las propiedades de proporcionar más de devolución o el establecimiento de un miembro. Le permiten agregar lógica que podría verificar un formato de entrada apropiado, validación de rango, etc.

La respuesta seleccionada del enlace lo expresa mejor, "Las propiedades proporcionan encapsulamiento. Puede encapsular cualquier validación/formato/conversión necesaria en el código para la propiedad. Esto sería difícil de hacer para los campos ".

http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42

0

Además de las otras respuestas que se mencionan aquí, los miembros públicos/protegidas que comienzan con un carácter de subrayado no son CLS-compliant, en la que no hay ningún requisito para lenguajes .NET para apoyar a los miembros con subrayado iniciales, por lo que alguien heredar de su clase en un idioma .NET diferente puede no ser capaz de acceder a ese miembro protegido en particular.

Lo sé, probablemente no se aplique a usted, pero podría ser parte del motivo de la advertencia de análisis de código.

Cuestiones relacionadas