2011-08-03 5 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 객체에 이벤트를 발생시킵니다. 도시에 여러 건물이있을 수 있으므로 각 건물에 처리기를 추가하고 싶지 않습니다. 또한 각 건물에 대해 두 가지 작업 (하나의 초기화 및 두 번째 목록에 추가, 하나는 새 건물 작성시 목록에 추가하는 것을 잊어 버림)을 각 목록에 추가하고 싶지 않습니다. 이를 위해 호출자는 컨트롤의 Parent 속성과 같이 호출자가 자동으로 사용할 수있게하려고합니다. (컨트롤에 this.Controls가 추가되었지만)

  2. 메모리를 사용하여 누가 현재 개체의 부모인지 알 수 있습니까? GC는 개체가 참조되지 않고 있음을 어떻게 알 수 있습니까 (작성자 포함). 메모리를 사용하여 호출자 객체를 식별하는 방법 (안전 또는 안전하지 않은)을 만들 수 있습니까? StackTrace를 사용하여 호출 hirarchy를 볼 수 있습니다. 새 객체가 생성 될 때 여기에서 인터셉트 할 수 있습니까?

+0

'부모'란 무엇을 의미합니까? – 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과 비교하면 기존 방식과 크게 다르지 않습니다. 단지 생성자가 아니라 메소드/속성을 통해 설정됩니다. 도시Print 같은 방법의 맥락에서만 필요한 경우 일부 사용을 고려하지 않고 매개 변수를 많이 복용보다, 다른 값을해야 할 수 있습니다

, 왜 등 즉, 매개 변수, nyTimes.Print(this)로에 통과하지 도시를 가지고 컨텍스트 개체의 종류 - 당신이 용어 부모창조자을 오용 생각

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 컬렉션에 있고 부모가 Form으로 설정되었음을 의미합니다.

이 문제로 인해 불일치가 발생할 수 있습니다 (Form1은 TextBox가 그 자식이라고 생각하지만 TextBox는 부모가 Form2라고 생각합니다). 그러나 잘 모르며 더 나은 것이 있다고 생각하지 않습니다. Children 컬렉션/Parent 참조보다 이러한 관계의 솔루션입니다.

0

여러분의 많은 질문 중 몇 가지를 따기 :이

이유를 통과 싫어

? 건물이 속한 도시를 말하고 있습니다. 어떻게 그럴 수 있니? 나는 이것을 객체를 연결하는 공통된 관용구로 생각합니다.그것은 각 건물에 대한 두 가지 작업 입니다 (하나의 초기화와 두 번째 는 새로운 건물을 작성할 때 목록에 추가하는 것을 잊지, 목록에 추가)로

또한 나는리스트로 각을 추가하지 않습니다. , GC에 관해서는

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

:

나는 당신에 추가하고 싶은 목록 명확하지 않다,하지만 당신은 기본 생성자에서 작업을 할 경우에 대한 우려는 극복 "망각" 일단 제작자가 무언가를 만들면 참조를 유지하기로 선택하지 않으면 이들 사이에 아무런 관계가 없습니다. 당신은

empEstate = new EmpEstate(this); 

에 너무 오래시는 쓰레기 collectio의 후보가 아니므로 다음 EmpState 중 하나를 수 없음을 했어요. 도시