C# 当造物主存在时,为什么对象是孤立的
考虑以下代码C# 当造物主存在时,为什么对象是孤立的,c#,design-patterns,memory-management,C#,Design Patterns,Memory Management,考虑以下代码 public class City { public string Name { get { return "New York"; } } Building empEstate; Building nyTimes; public void Init() { // I hate passing "this" to all object em
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);
}
}
如果该城市仅适用于诸如“代码>打印< /代码>等方法的上下文,为什么不将其作为参数传递,即<代码> NyTimes?打印(此)< /代码>等。如果您可能需要其他值,而不是获取大量参数,请考虑使用具有城市的上下文对象-即
class PrintContext {
public City City {get;private set;}
// other stuff...
public PrintContext(City city/*, other stuff...*/) {
City = city;
}
}
我认为你误用了父母和创造者这两个词。创建实例的对象与实例没有特殊关系(例如,工厂创建对象,但不维护对它们的引用),因此,一般来说,无法确定是谁或是什么创建了具体实例。
在同样的意义上,父对象对一般对象没有意义。我们可以推断表单是文本框的父对象,但这不是一种特殊的关系。在这种情况下,它只意味着文本框位于表单的Contols集合中,并且它的父项设置为表单
您是对的,这可能会导致不一致(Form1认为TextBox是它的子项,但TextBox认为它的父项是Form2),但我不知道,不要认为这种关系有比
儿童
集合家长参考更好的解决方案。从你的许多问题中挑选一些:
我讨厌传递这个
为什么??你在告诉那栋楼它属于哪个城市。你还能怎么做呢。我认为这是将对象连接在一起的常见习惯用法
另外,我不想将它们都添加到列表中,因为这是两项任务
对于每个建筑(一个初始化和第二个添加到列表,一个
写新建筑时忘记添加到列表)
我不清楚您想将它们添加到哪个列表中,但如果您在基本构造函数中进行工作,您对“遗忘”的担忧就不会出现了:
public Building(City city){
this._city = city;
// add the building to the list here - nothing to "forget"
}
至于GC,一旦创建者创建了一些东西,它们之间就没有关系,除非您选择保留引用。你已经和我一起做了
empEstate = new EmpEstate(this);
因此,只要城市不是垃圾收集的候选城市,那么EmpState也不会成为垃圾收集的候选城市。在城市上建造工厂解决了我将垃圾收集传递给每个对象的问题
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();
}
}
公共接口
{
字符串名称{get;}
}
公共抽象类城市:城市
{
公共建筑(
{
T buildingInstance=Activator.CreateInstance();
((i建筑)站姿)设置城市(本);
回归建筑立场;
}
公共抽象字符串名称{get;}
}
界面IBuilding
{
城市{get;}
无效城市(城市);
}
公共抽象类构建:IBuilding
{
私立城市;
公共城市{get{return{u City;}
公共空间IBuilding.SetCity(城市)
{
这个。_city=城市;
}
公共抽象字符串名称{get;}
公开作废印刷品()
{
Console.WriteLine(此.Name);
控制台。写(“,”;
Console.WriteLine(此城市名称);
}
}
公共类国家:建筑
{
公共重写字符串名称{get{返回“Emp状态”;}
}
《纽约时报》公共课:建筑
{
公共重写字符串名称{get{return“NY Times”;}
}
公共课纽约市:城市
{
公共重写字符串名称{get{return“New York”;}
EmpEstate EmpEstate;
纽约时报;
公共void Init()
{
//现在我不需要通过这个考试
empEstate=this.CreateBuilding();
setSomeProperty(empEstate);
//现在,任何人都无法在新的和中创建建筑
//说它属于菲利德尔菲亚:)
nyTimes=this.CreateBuilding();
}
公共地址()
{
emperstate.Print();
Print();
}
}
问题是已经创建了几个类,对于新功能,我们需要在Building对象的基类中使用creator对象。我们不想修改每个类的构造函数并将此对象传递给每个类。City类(在示例中)基本上是插件端的代码,所以允许他们通过City(如果插件开发者通过错误的城市)可能会干扰整个应用程序的功能。因此,修改插件库解决了我的问题。欢迎您提出建议。您所说的“家长”是什么意思?家长您可以说是声明或创建对象的对象。我喜欢您作为PrintContext的想法,但正如我所说的,城市需要处理每栋建筑引发的事件,在这里,这种方法行不通。