2009-12-21 4 views
21

J'ai une classe "meter". Une propriété de "meter" est une autre classe appelée "production". Je dois accéder à une propriété de la classe de compteur (puissance nominale) de la classe de production par référence. Le powerRating n'est pas connu à l'instanciation de Meter.Comment accéder à l'objet parent en C#

Comment puis-je faire cela?

Merci à l'avance

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

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

Copie possible de [Quelle est la meilleure façon d'accéder au champ dans la classe englobante de la classe imbriquée?] (Http://stackoverflow.com/questions/185124/whats-the-best-way-of-accessing-field -in-the-enclosing-class-from-the-nested-cl) –

+2

@JimFell Ceci n'implique pas du tout les classes imbriquées – Rob

Répondre

28

magasin une référence à l'instance de compteur en tant que membre de production:

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

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

Et puis dans l'appareil de classe:

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

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

Notez également que vous devez mettre en œuvre une méthode accesseur/propriété pour que la classe Production puisse réellement accéder au membre powerRating de la classe Meter.

+0

Que se passe-t-il si les deux classes sont dans des assemblages différents et que l'assemblage contenant un compteur a une référence de projet VS2010 à l'assemblage contenant la production? – Snowy

+1

@Snowy: Les références cycliques n'étant pas possibles, vous devez réorganiser votre implémentation et déplacer une classe vers une autre (ou dupliquer la classe, si rien d'autre ne vous aide). – Christian

9

Vous devez ajouter une propriété à votre classe de production et le mettre au point en arrière à son parent, il n'existe pas par défaut.

-3

quelque chose comme ceci:

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

C'est une relation parent/enfant, pas une relation "héritée". – GalacticCowboy

+0

@ GalacticCowboy, oh oui, je vois ce que tu veux dire. Silly me –

2

Pourquoi ne pas changer le constructeur sur Production pour vous permettre de passer dans une référence au moment de la construction:

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

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

Dans le constructeur Production vous pouvez attribuer à un champ privé ou une propriété. Alors Production aura toujours accès à son parent.

0

Vous pouvez peut-être ajouter une méthode à votre objet Production appelée 'SetPowerRating (int)' qui définit une propriété dans Production, et l'appelle dans votre objet Meter avant d'utiliser la propriété dans l'objet Production?

+0

Je pense que cela viole KISS; avoir à rappeler d'appeler une fonction avant d'appeler une propriété rend l'OMI trop compliquée. –

+0

Certes, le design ci-dessus sonne comme si elle avait besoin d'être repensée. Je viens de fournir une solution et ce n'est probablement pas la meilleure. –

26

Je ne ferais pas référence au parent directement dans les objets enfants. À mon avis, les enfants ne devraient rien savoir des parents. Cela limitera la flexibilité!

Je résoudrais cela avec des événements/gestionnaires.

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

Dans ce cas, je l'ai résolu avec le Func <> générique, mais peut être fait avec des fonctions « normales ». C'est pourquoi l'enfant (Production) est totalement indépendant de son parent (Meter).


But! S'il y a trop d'événements/gestionnaires ou vous voulez juste passer un objet parent, je résoudraient avec une interface:

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

Cela ressemble à peu près la même chose que la solution mentionne, mais pourrait être défini l'interface dans un autre assemblage et peut être mis en œuvre par plus de 1 classe.


Cordialement, Jeroen van Langen.

Questions connexes