2010-04-22 2 views
6

L'altro giorno ho riscontrato un piccolo problema relativo alle proprietà di C#.Numero di proprietà C#

Diciamo che ho questa messa a punto:

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 
    } 
} 

Questo è tutto bene, ma quando si tratta di utilizzo, ho potuto scrivere qualcosa di simile:

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

Il fatto è che la mia classe Control non riconoscerà che lo Position è stato modificato perché non è stato chiamato set().

C'è un modo per rendere Control consapevole di eventuali modifiche Position?

+1

Intendi "Posizione punto pubblico" come proprietà, non "Posizione pubblica"? – Lazarus

+0

Sì, mio ​​errore. – impmja

+0

Se vuoi che X e Y siano pubblici, è meglio struct Point che class Point –

risposta

-3

Questo dovrebbe risolvere il problema! Ho aggiunto una riga nel tuo getter che verifica se il punto è nullo e se lo istanzia prima di tornare.

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

Se le persone stanno andando giù vota almeno un commento per fornire un motivo!Il codice sopra risolverà direttamente il problema dell'OP e consentirà al codice di funzionare come nell'esempio dell'OP. – OneSHOT

+0

Perché? Questo chiaramente non risolverà il problema che sta avendo e perché controlli per null se m_Position è inizializzato quando si crea il controllo – RvdK

+0

Non ho fatto downvote, ma non risolverà il problema degli OP, perché come già detto, il setter non sarà mai essere chiamato, solo il getter. – Alfonso

0

Si potrebbe fare un public class Pointpublic struct Point. In questo modo, il compilatore ti costringerà a scrivere

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

e il setter della proprietà viene chiamato.

+0

Bene, questo arriva alla soluzione che Tom Cabanski ha pubblicato, rendendo Point immutabile. Questo è probabilmente il modo "migliore" per ottenere più controllo. Il punto è, il suo tipo di non flessibile. Mi chiedo davvero perché C# non lo implementa in primo luogo .. – impmja

7

Ci sono una serie di opzioni in questo caso:

  1. Fai le proprietà X e Y della vostra classe Point immutabile. Cioè, richiedere all'utente di creare un nuovo punto ogni volta che X o Y cambia.
  2. Imposta un evento sulla classe Point e iscriviti ad esso nella classe Position. Ogni volta che il punto cambia X o Y, attiva l'evento. La classe Position può gestire gli effetti collaterali nel gestore eventi.

In questo caso, vorrei suggerire l'opzione # 1

+1

Una terza variante, se è necessario aggiornare X e Y molto spesso, sarebbe abbandonare completamente la classe Point e avere due proprietà PositionX e PositionY sulla classe. In questo caso è più efficiente della creazione di un nuovo oggetto/attivazione di un evento ogni volta che qualcosa cambia. – Alfonso

+0

Punto eccellente! –

+1

Invece della tua prima proposta, penso che sarebbe meglio usare una struct per la classe Point. – Danvil

1

1) Fare Point.X e punto.Ý privato. 2) Aggiungere proprietà per X e Y a punto. 3) Aggiungi un evento a Punto che viene generato quando X o Y vengono modificati. 4) Registra il controllo come ascoltatore per gli eventi che vengono generati da Point.

2

La dichiarazione myControl.Position.X = 1.0f; in realtà chiama il getter e non il setter della proprietà Position. Un modo di fare ciò che si vuole fare potrebbe essere esponendo i valori X e Y direttamente sulla tua classe, in questo modo:

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 
    } 
} 

Un altro modo sarebbe quello di implementare qualche evento sulla classe Position che viene sollevata ogni l'ora X o Y cambia. Ciò comporterebbe la creazione di X e Y in proprietà sull'oggetto Point e la generazione di un evento ogni volta che vengono modificati. Il tuo controllo dovrebbe quindi iscriversi a quell'evento.

+0

Funziona davvero, ma poi non posso più usare Position direttamente che cerco di mantenere :) – impmja