web-dev-qa-db-ja.com

C#で親オブジェクトにアクセスする方法

「メーター」クラスがあります。 「メーター」の1つのプロパティは、「生産」と呼ばれる別のクラスです。 referenceにより、生産クラスからメータークラス(電力定格)のプロパティにアクセスする必要があります。 powerRatingは、Meterのインスタンス化ではわかりません。

どうやってやるの ?

前もって感謝します

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

   public Meter()
   {
      _production = new Production();
   }
}
29
Jean Duprez

Productionのメンバーとしてメーターインスタンスへの参照を保存します。

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

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

そして、Meterクラスで:

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

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

また、ProductionクラスがMeterクラスのpowerRatingメンバーに実際にアクセスできるように、アクセサーメソッド/プロパティを実装する必要があることに注意してください。

41
Christian

子オブジェクトで親を直接参照しません。私の意見では、子供は親について何も知らないはずです。これは柔軟性を制限します!

これをイベント/ハンドラーで解決します。

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

この場合、Func <>ジェネリックで解決しましたが、「通常の」関数で実行できます。これが、子(生産)が親(メーター)から完全に独立している理由です。


だが!イベント/ハンドラが多すぎる場合、または単に親オブジェクトを渡したい場合は、インターフェイスで解決します:

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

これはソリューションの説明とほとんど同じように見えますが、インターフェイスは別のアセンブリで定義でき、複数のクラスで実装できます。


よろしく、Jeroen van Langen。

31
Jeroen

Productionクラスにプロパティを追加し、その親を指すように設定する必要があります。これはデフォルトでは存在しません。

9
bwarner

Productionのコンストラクターを変更して、構築時に参照を渡すようにしてください:

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

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

Productionコンストラクターで、これをプライベートフィールドまたはプロパティに割り当てることができます。そうすると、Productionは常に親にアクセスできます。

3
Rob Levine

Productionオブジェクトにプロパティを設定する 'SetPowerRating(int)'というメソッドをProductionオブジェクトに追加し、Productオブジェクトでプロパティを使用する前にMeterオブジェクトでこれを呼び出すことができますか?

0
Gary Willoughby