2010-04-22 12 views
6

El otro día me encontré con un pequeño problema con respecto a las propiedades de C#.C# propiedades problema

Digamos que tengo esta configuración:

public class Point 
{ 
public float X; 
public float Y; 
} 

public class Control 
{ 
protected Point m_Position = new Point(); 

public Point Position 
{ 
    get { return m_Position; } 
    set 
    { 
    m_Position = value; } 
    // reorganize internal structure.. 
    reorganize(); 
    } 

    protected reorganize() 
    { 
    // do some stuff 
    } 
} 

esto está bien, pero cuando se trata de uso, podría escribir algo como:

Control myControl = new Control(); 
myControl.Position.X = 1.0f; 

La cosa es que mi clase Control no reconocerá que se ha cambiado el Position porque no se ha llamado al set().

¿Hay alguna manera de hacer que Control tenga conocimiento de algún cambio en Position?

+1

¿Quiere decir 'public Point Position' como propiedad, no' public Position'? – Lazarus

+0

Sí, mi error. – impmja

+0

Si desea que X e Y sean públicos, es mejor estructurar Punto que clase Punto –

Respuesta

-3

¡Esto debería solucionarlo! He agregado una línea en su getter que prueba para ver si el punto es nulo y si es instanciarlo antes de regresar.

public class Point 
{ 
public float X; 
public float Y; 
} 

public class Control 
{ 
protected Point m_Position = new Point(); 

public Point Position 
{ 
    get 
    { 
     if (m_Position == null) m_Position = new Point(); 
     return m_Position; 
    } 
    set 
    { 
    m_Position = value; 
    // reorganize internal structure.. 
    reorganize(); 
    } 

    } 

    protected reorganize() 
    { 
    // do some stuff 
    } 
} 

HTH

+0

Si la gente va a votar, ¡por lo menos publique un comentario para proporcionar una razón!El código anterior resolverá directamente el problema del OP y permitirá que el código funcione según el ejemplo del OP. – OneSHOT

+0

¿Por qué? Esto claramente no solucionará el problema que está teniendo y por qué verificar nulo si m_Position se inicializa al crear el control – RvdK

+0

No devolví, pero no resolverá el problema de OP, porque como él ya lo mencionó, el colocador nunca lo hará ser llamado, solo el captador. – Alfonso

0

Se podría hacer una public class Pointpublic struct Point. De esta forma, el compilador lo forzará a escribir

myControl.Position = new Point() { X = 1.0f, Y = myControl.Position.Y; } 

y se llama a la propiedad setter.

+0

Bueno, esto se debe a la solución que Tom Cabanski publicó, por lo que Point es inmutable. Esta es probablemente la "mejor" forma de lograr más control. El punto es, es tipo de unflexable. Realmente me pregunto por qué C# no implementa esto en primer lugar. – impmja

7

Hay una serie de opciones en este caso:

  1. que las propiedades X e Y de la clase Punto inmutable. Es decir, requiere que el usuario cree un nuevo Punto siempre que X o Y cambie.
  2. Configura un evento en la clase Point y suscríbete a él en la clase Position. Siempre que la X o Y del Punto cambie, activa el evento. La clase de posición puede manejar efectos secundarios en el controlador de eventos.

En este caso, sugeriría la opción # 1

+1

Una tercera variante, si necesita actualizar X e Y muy a menudo, sería abandonar completamente la clase Point y tener dos propiedades PositionX y PositionY en la clase. En este caso, es más eficiente que crear un nuevo objeto/disparar un evento cada vez que algo cambia. – Alfonso

+0

¡Excelente punto! –

+1

En lugar de su primera propuesta, creo que sería mejor usar una estructura para la clase Point. – Danvil

1

1) Hacer punto.x y Punto.y privado. 2) Agregue propiedades para X e Y a punto. 3) Agregue un evento al Punto que se genera cuando se modifican X o Y. 4) Registre Control como un oyente para los eventos que se plantean por Punto.

2

En realidad, la declaración myControl.Position.X = 1.0f; llama al captador y no al colocador de su propiedad Position. Una manera de hacer lo que quiere hacer podría ser mediante la exposición de los valores X e Y directamente en su clase, así:

public class Control 
{ 
protected Point m_Position = new Point(); 

public float PositionX 
{ 
    get { return m_Position.X; } 
    set 
    { 
    m_Position.X = value; } 
    // reorganize internal structure.. 
    reorganize(); 
    } 

    ... Same thing for PositionY 

    protected reorganize() 
    { 
    // do some stuff 
    } 
} 

Otra forma sería la de poner en práctica algún evento en la clase Position que se levanta cada tiempo X o Y cambio. Esto implicaría convertir X e Y en propiedades en el objeto Point, y generar un evento cada vez que se modifiquen. Su control tendría que suscribirse a ese evento.

+0

Esto realmente funciona, pero luego no puedo usar la posición directamente más que intento mantener :) – impmja