2009-12-21 15 views
21

Tengo una clase "meter". Una propiedad de "meter" es otra clase llamada "producción". Necesito acceder a una propiedad de la clase del medidor (clasificación de potencia) de la clase de producción por referencia. PowerRating no se conoce en la instanciación de Meter.Cómo acceder al objeto principal en C#

¿Cómo puedo hacer eso?

Gracias de antemano

public class Meter 
{ 
    private int _powerRating = 0; 
    private Production _production; 

    public Meter() 
    { 
     _production = new Production(); 
    } 
} 
+0

Posible duplicado de [¿Cuál es la mejor forma de acceder al campo en la clase adjunta de la clase anidada?] (Http://stackoverflow.com/questions/185124/whats-the-best-way-of-accessing-field -en-la-clase-envolvente-desde-la-anidada-cl) –

+2

@JimFell Esto no implica clases anidadas en absoluto – Rob

Respuesta

28

almacenar una referencia a la instancia metros como miembro de Producción:

public class Production { 
    //The other members, properties etc... 
    private Meter m; 

    Production(Meter m) { 
    this.m = m; 
    } 
} 

Y luego, en la clase del medidor:

public class Meter 
{ 
    private int _powerRating = 0; 
    private Production _production; 

    public Meter() 
    { 
     _production = new Production(this); 
    } 
} 

También tenga en cuenta que es necesario poner en práctica un método de acceso/propiedad para que la clase Production pueda acceder al miembro powerRating de la clase Meter.

+0

¿Qué sucede si las dos clases están en ensamblajes diferentes, y el ensamblaje que contiene el medidor tiene una referencia de proyecto VS2010 al ensamblaje que contiene producción? – Snowy

+1

@Snowy: como las referencias cíclicas no son posibles, necesitarás reorganizar tu implementación y mover una clase a otro ensamblado (o duplicar la clase, si nada más ayuda). – Christian

9

Usted tendría que añadir una propiedad a su categoría de Producción y configurarlo para que apunte hacia atrás en su matriz, esto no existe de forma predeterminada.

-3

algo como esto:

public int PowerRating 
    { 
     get { return base.PowerRating; } // if power inherits from meter... 
    } 
+0

Es una relación padre/hijo, no una relación "hereda". – GalacticCowboy

+0

@GalacticCowboy, oh sí, entiendo a qué te refieres. Tonto yo –

2

por qué no cambiar el constructor en Production dejar que se pasa en una referencia en el momento de la construcción:

public class Meter 
{ 
    private int _powerRating = 0; 
    private Production _production; 

    public Meter() 
    { 
     _production = new Production(this); 
    } 
} 

En el Production constructor puede asignar a un campo privado o una propiedad. Entonces Production siempre tendrá acceso a parent.

0

¿Podría agregar un método a su objeto de producción llamado 'SetPowerRating (int)' que establece una propiedad en Producción y lo llama en su objeto Meter antes de usar la propiedad en el objeto Production?

+0

Creo que esto viola a KISS; tener que recordar llamar a una función antes de llamar a una propiedad lo hace demasiado complicado IMO. –

+0

Cierto, el diseño anterior suena como si necesitara un replanteo completo. Acabo de suministrar una solución y probablemente no sea la mejor. –

26

No haría referencia al elemento primario directamente en los objetos secundarios. En mi opinión, los niños no deberían saber nada sobre los padres. ¡Esto limitará la flexibilidad!

Resolvería esto con eventos/controladores.

public class Meter 
{ 
    private int _powerRating = 0; 
    private Production _production; 

    public Meter() 
    { 
     _production = new Production(); 
     _production.OnRequestPowerRating += new Func<int>(delegate { return _powerRating; }); 
     _production.DoSomething(); 
    } 
} 

public class Production 
{ 
    protected int RequestPowerRating() 
    { 
     if (OnRequestPowerRating == null) 
      throw new Exception("OnRequestPowerRating handler is not assigned"); 

     return OnRequestPowerRating(); 
    } 

    public void DoSomething() 
    { 
     int powerRating = RequestPowerRating(); 
     Debug.WriteLine("The parents powerrating is :" + powerRating); 

    } 

    public Func<int> OnRequestPowerRating; 
} 

En este caso lo resolví con el Func <> genérico, pero se puede hacer con las funciones 'normales'. Este es el motivo por el cual el niño (Producción) es totalmente independiente de su padre (Medidor).


But! Si hay demasiados eventos/manejadores o simplemente quieren pasar un objeto padre, lo resolvería con una interfaz:

public interface IMeter 
{ 
    int PowerRating { get; } 
} 

public class Meter : IMeter 
{ 
    private int _powerRating = 0; 
    private Production _production; 

    public Meter() 
    { 
     _production = new Production(this); 
     _production.DoSomething(); 
    } 

    public int PowerRating { get { return _powerRating; } } 
} 

public class Production 
{ 
    private IMeter _meter; 

    public Production(IMeter meter) 
    { 
     _meter = meter; 
    } 

    public void DoSomething() 
    { 
     Debug.WriteLine("The parents powerrating is :" + _meter.PowerRating); 
    } 
} 

Esto se ve más o menos la misma que la solución menciona, pero la interfaz se podría definir en otro ensamblado y puede implementarse en más de 1 clase.


Saludos, Jeroen van Langen.

Cuestiones relacionadas