2011-08-03 6 views
0

は、次のコードを検討存在する場合、孤児ですなぜオブジェクトは、作成者が

public class City 
    { 
     public string Name { get { return "New York"; } } 

     Building empEstate; 
     Building nyTimes; 
     public void Init() 
     { 
      // I hate passing "this" to all object 
      empEstate = new EmpEstate(this); 
      setSomeProperty(empEstate); 
      // any one can create new object of some other city 
      // and pass to the building 
      nyTimes = new NYTimes(this); 
      ... 
      other = new OtherBuildings(this) 
     } 

     public void PrintAddresses() 
     { 
      empEstate.Print(); 
      nyTimes.Print(); 
      ... 
      other.Print(); 
     } 
    } 

    public abstract class Building { 
     City _city; 
     public Building(City city){ 
      this._city = city; 
     } 
     public abstract string Name { get;} 
     public void Print(){ 
      Console.WriteLine(this.Name); 
      Console.Write(","); 
      Console.WriteLine(this._city.Name); 
     } 
    } 
  1. 私はこのアプローチのよりよい解決策を望んで最初のもの。印刷は単なる例です。実際には、各建物オブジェクトはCityオブジェクトに対して何らかのイベントを発生させます。私は都市にいくつかの建物が存在する可能性があるので、各建物にハンドラを追加したくありません。また、各建物の2つのタスク(1つの初期化と2つ目のリストへの追加、1つは新しい建物の作成時にリストに追加することを忘れてしまいます)をリストに追加したくありません。このため、コントロールの親プロパティ(これはthis.Controlsに追加されていますが)のように呼び出し元に自動的に呼び出されるようにします。

  2. メモリを使用して、誰が現在のオブジェクトの親であるかを知ることができます。オブジェクトが参照されていないことをGCがどのように知っているか(作成者を含む)メモリを使用して呼び出し元オブジェクトを識別するメソッド(安全かどうか)を作成できません。私はStackTraceを使って呼び出しの階層を見ることができます。新しいオブジェクトが作成されたときにここで傍受できますか?

+0

あなたは 'parent'でも何を意味しますか? – CodesInChaos

+0

親は、オブジェクトが宣言されたオブジェクトまたは作成されたオブジェクトを言うことができます。 – hungryMind

答えて

1

ビル工場は

public interface ICity 
    { 
     string Name { get; } 
    } 
    public abstract class City : ICity 
    { 
     public T CreateBuilding<T>() 
     { 
      T buildingInstance = Activator.CreateInstance<T>(); 
      ((IBuilding)buildingInstance).SetCity(this); 
      return buildingInstance; 
     } 

     public abstract string Name { get; } 
    } 

    interface IBuilding 
    { 
     ICity City { get; } 
     void SetCity(ICity city); 
    } 
    public abstract class Building : IBuilding 
    { 
     private ICity _city; 
     public ICity City { get { return _city; } } 
     public void IBuilding.SetCity(ICity city) 
     { 
      this._city = city; 
     } 
     public abstract string Name { get; } 
     public void Print() 
     { 
      Console.WriteLine(this.Name); 
      Console.Write(","); 
      Console.WriteLine(this._city.Name); 
     } 
    } 
    public class EmpEstate : Building 
    { 
     public override string Name { get { return "Emp State"; } } 
    } 
    public class NYTimes : Building 
    { 
     public override string Name { get { return "NY Times"; } } 
    } 
    public class NewYorkCity : City 
    { 
     public override string Name { get { return "New York"; } } 

     EmpEstate empEstate; 
     NYTimes nyTimes; 
     public void Init() 
     { 
      // Now I dont need to pass this 
      empEstate = this.CreateBuilding<EmpEstate>(); 
      setSomeProperty(empEstate); 
      // now any one cannot create building in new your and 
      // say it belongs to Philedelphia :) 
      nyTimes = this.CreateBuilding<NYTimes>(); 
     } 

     public void PrintAddresses() 
     { 
      empEstate.Print(); 
      nyTimes.Print(); 
     } 
    } 

問題がすでに作成され、いくつかのクラスがあって、新しい機能のために私たちは建物のオブジェクトの基本クラスでクリエータオブジェクトを必要とした各オブジェクトにこれを渡すの私の問題を解決しました。各クラスのコンストラクタを変更し、このオブジェクトをそれぞれに渡すことは望まなかった。 Cityクラス(例では)は基本的にプラグイン側のコードなので、プラグインデベロッパーが間違った都市を渡した場合、都市を渡すことができ、アプリ全体の機能が妨げられる可能性があります。だから、プラグインのベースを修正することは私の目的を解決しました。提案は大歓迎です。

0

オブジェクトの論理的な「所有者」はありません。スタックトレースを検査することは、通常は理想的ではありません。 Parentと比較すると、それはあなたの既存のアプローチとあまり変わりません。コンストラクタではなくメソッド/プロパティによって設定されます。

はあなたではなく、パラメータの多くを取る以外の値を、必要な場合があります場合は、いくつかの使用を検討して、なぜ、それをパラメータとして渡すない、すなわちnyTimes.Print(this)など、Printような方法の文脈のために必要なだけであるならば都市を持っていることをコンテキストオブジェクトの種類は - 私はあなたが条件クリエイターを悪用していると思う

class PrintContext { 
    public City City {get;private set;} 
    // other stuff... 
    public PrintContext(City city/*, other stuff...*/) { 
      City = city; 
    } 
} 
+0

私はあなたのアイデアがPrintContextとして好きでしたが、私は都市が各建物で発生したイベントを処理する必要があると言ったように、このアプローチはうまくいきません。 – hungryMind

0

、すなわち。インスタンスを作成したオブジェクトはインスタンスと特別な関係はありません(たとえば、ファクトリはオブジェクトを作成しますが、オブジェクトへの参照は保持しません)。したがって、一般的に、具体的なインスタンスを作成した者や作成者を見つける方法はありません。同じ意味で、は、一般的な目的では意味を持たない。 FormがTextBoxの親であるとはどういうわけか推測できますが、それは特別な関係ではありません。この場合は、TextBoxがフォームのContolsコレクションにあり、その親がフォームに設定されていることを意味します。

あなたは、これが潜在的に(Form1がテキストボックスには、それは子供のですが、テキストボックスには、それは親がForm2をさだと考えていると考えている)の矛盾につながる可能性があることを右ですが、私は知らない、と良くないと思いますこの種の関係の解はChildrenコレクション/ Parent参照よりも優れています。あなたの多くの質問のいくつかのピッキング

0

を私はこの

なぜを渡す嫌い?あなたはそれが所属する都市を建物に伝えています。他にどのようにこれを行うことができます。私はそれを一緒にオブジェクトを配線するための共通のイディオムと見ています。

また、私はそれが各建物のための2つのタスク あるとして(1つの初期化及び第二のリストに追加し、1 は新しい建物を書くときに、リストに追加するのを忘れ)、リストにそれらのそれぞれを追加する必要はありません。 、GC用として

public Building(City city){ 
     this._city = city; 
     // add the building to the list here - nothing to "forget" 
    } 

は、私はあなたがそれらを追加したいものをリスト明確でないんだけど、あなたは基本コンストラクタで作業を行う場合について、あなたの懸念が解消される「忘却します」作成者が何かを作成すると、参照を保持しない限り、それらの間には何の関係もありません。あなたは

empEstate = new EmpEstate(this); 

とその限り市がごみcollectioの候補ではないとして、その後EmpStateはどちらでもないことを行っています。街の

関連する問題