2009-05-11 29 views
6

Si tengo una variable privada en la que deseo tener una validación interna, y quiero mantener esa validación en un solo lugar, la ubico detrás de un getter/setter y solo acceda a él por ese getter/setter. Eso es útil cuando se trata de propiedades públicas, porque el otro código no puede acceder a la variable privada, pero cuando trato con un objeto dentro de la misma clase, ¿hay alguna forma de aplicar el getter/setter?force get/set acceso de variables privadas para propiedades privadas

private int _eyeOrientation; 

    private int eyeOrientation 
    { 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     if (value < 0) 
     { 
      _eyeOrientation = 0; 
     } 
     else 
     { 
      _eyeOrientation = value % 360; 
     } 
    } 
    } 

El problema aquí es que las otras funciones de la clase pueden modificar accidentalmente

_eyeOrientation = -1;

que lanzar el programa en un manojo de nervios. ¿Hay alguna forma de conseguir que arroje un error de compilación?

+7

Es un día triste cuando codificadores ya no pueden confiar en otras funciones dentro de la misma clase: – codeulike

Respuesta

10

Parece que necesita un tipo de ángulo.

// Non mutable Angle class with a normalized, integer angle-value 
public struct Angle 
{ 
    public Angle(int value) 
    { 
    Value = value; 
    } 

    private angle; 
    public Value 
    { 
    get { return angle; } 
    private set { angle = Normalize(value); } 
    } 

    public static int Normalize(int value) 
    { 
    if (value < 0) return 360 - (value % 360); 
    return value % 360; 
    } 
} 

public class SomeClass 
{ 
    public Angle EyeOrientation { get; set; } 
} 

Si usted tiene un cierto tipo de valor, como ángulos, el dinero, el peso o lo que sea, siempre es una buena praxis para que sea un propio tipo, incluso si el valor en sí se almacena en un int, decimal etc. Este tipo hace que sus interfaces sean más claras y seguras. No es lo mismo si espera un ángulo o un valor entero como argumento de algún método.

4

Puede definirlo en una clase anidada.

public class NeedsEye 
{ 

    Eye _eye = new Eye(); 

    public NeedsEye() 
    { 
     // now, here, any access to the property must be made through the 
     // _eye variable. The Eye class has access to any of the properties 
     // and members of the NeedsEye class, but the NeedsEye class has not 
     // any access to members of the Eye class. 
    } 

    private class Eye 
    { 
     private int _orientation; 

     public int Orientation 
     { 
      get { return _orientation; } 

      if (value < 0) 
      { 
       _eyeOrientation = 0; 
      } 
      else 
      { 
       _eyeOrientation = value % 360; 
      }  
     } 
    } 
} 
1

Simplemente ponga su atributo privado y getters/setters públicos en una clase privada.

Luego, solo el captador y el colocador pueden acceder al atributo privado.

Es exagerado, pero funcionaría. :)

9

En general, no debe preocuparse por esto. Los miembros de la clase todavía pueden usar las propiedades, si no desea poner la verificación en la clase en sí.

Si su clase es tan grande que ya no confía en los métodos dentro de la clase, creo que es hora de comenzar a refactorizar y dividir esto en clases más pequeñas que sean más fáciles de administrar.

+0

) Estoy trabajando en un proyecto personal donde yo estoy tratando de ser lo más estricta posible con acceso. Solo para ver si es posible tener todos sus objetos SOLO accesibles para los objetos que los necesitan. No los necesita si sigue las buenas prácticas de codificación, pero tenía curiosidad si era posible. – DevinB

1

Dependiendo de las herramientas que usted podría mirar en la aplicación de una convención de codificación no permitir el acceso directo a un miembro privado fuera un get/set

Podría ser un trabajo más, pero usted no tendrá que crear una serie de envoltura clases

3

Puede marcar el campo como obsoleto para que el compilador genere una advertencia si intenta acceder a él, y luego suppress that warning para la propiedad getter/setter.

Los códigos de advertencia que debe suprimir son CS0612 for the plain Obsolete attribute y CS0618 if the attribute has a custom message.

En general, consideraría esto como un hack y trataré de evitarlo si es posible. Una mejor solución sería comentar el código de manera apropiada y capacitar a los desarrolladores para que hagan lo correcto.

[Obsolete("Please use the EyeOrientation property instead.")] 
private int _eyeOrientation; 

public int EyeOrientation 
{ 
    #pragma warning disable 612, 618 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     _eyeOrientation = (value > 0) ? value % 360 : 0; 
    } 
    #pragma warning restore 612, 618 
} 
+1

(+1) Es una solución ingeniosamente redonda – DevinB

+0

Es una buena idea, pero no lo pondría en 0, porque un ángulo negativo podría normalizarse a positivo, por ejemplo. -10 ° == 350 °. –

+0

@Stefan, estoy de acuerdo. Solo estaba duplicando la funcionalidad del código de ejemplo en la pregunta. – LukeH

Cuestiones relacionadas