我很感激帮助重构我的代码。如果我将一个对象的实例传递给另一个对象实例,有没有办法重新实例化该实例而不会丢失引用?
以下是我遇到的问题的简化版本:
public class Program
{
static void Main(string[] args)
{
Animal myPet = new Cat();
House myHouse = new House(myPet);
House petDayCare = new House(myPet);
Console.WriteLine(String.Format("My pet has {0} flea(s)", myPet.Fleas.ToString()));
myHouse.AddFlea();
Console.WriteLine(String.Format("My pet has {0} flea(s)", myPet.Fleas.ToString()));
petDayCare.AddFlea();
Console.WriteLine(String.Format("My pet has {0} flea(s)", myPet.Fleas.ToString()));
myHouse.GetNewPet();
Console.WriteLine(String.Format("My pet has {0} flea(s)", myPet.Fleas.ToString()));
Console.ReadLine();
}
}
public class House
{
Animal _currentPet;
public House(Animal currentPet) {
_currentPet = currentPet;
}
public Animal CurrentPet {
get { return _currentPet; }
set { _currentPet = value; }
}
public void AddFlea() {
_currentPet.Fleas += 1;
}
public void GetNewPet() {
Animal rover = new Dog();
rover.Fleas = 100;
_currentPet = rover;
}
}
public abstract class Animal {
int _fleas;
public int Fleas {
get { return _fleas; }
set { _fleas = value; }
}
public abstract string GetSound();
}
public class Cat : Animal
{
public override string GetSound() {
return "Meow";
}
}
public class Dog : Animal
{
public override string GetSound()
{
return "Woof";
}
}
调用GetNewPet()后,myPet.Fleas在程序中可以为100吗?
如果我想更改对象实例的基础类型,我可以这样做吗?如果没有,是否有人有任何重构建议?
我将尝试描述实际程序结构的细节。
我正在创建一个WPF向导。
该向导有步骤。
当我启动向导时,会创建一个WizardViewModel类的实例。
WizardViewModel类有一个ObjectX实例(一个对象,我想要修改属性,然后在向导完成时返回该对象)。
向导中的每个步骤都是WizardPageViewModelBase类的一个实例,它在构造函数中传递一个ObjectX实例。
WizardViewModel有一个WizardPageViewModelBase对象列表(每个向导步骤都有一个对象实例)。
因此,只要我在每个向导步骤(WizardPageViewModelBase对象实例)中更改ObjectX实例的属性,WizardViewModel返回的对象就可以正常工作。
但是,在向导的第1步中,我想根据用户从列表框中选择的内容来更改ObjectX的基础类型。如果我更改实例(就像我在上面的GetNewPet()中那样),则会失去对WizardViewModel中ObjectX实例的引用。
道歉,如果这没有意义,我尽力以可以回答的方式构建问题......
答案 0 :(得分:1)
你从不使用House的宠物。
即使你打电话myHouse.GetNewPet()有效地取代myHouse的CurrentPet,也没关系,因为你从不使用当前宠物。
您的主程序仅使用myPet,它始终是您在开始时创建的Cat。
所以,实际上,你的问题不在于你失去了对Animal的引用,而是你从未放弃过引用的开头。
我想你打算做的事情是:
Console.WriteLine(String.Format("My pet has {0} flea(s)",
myHouse.CurrentPet.Fleas.ToString()));
答案 1 :(得分:0)
使用以下代码,其中_fleas是静态的,我可以得到“我的宠物有100只跳蚤”,但我不确定这是否是你想要的:
public abstract class Animal
{
static int _fleas;
public int Fleas
{
get { return _fleas; }
set { _fleas = value; }
}
public abstract string GetSound();
}
答案 2 :(得分:0)
您的问题的描述似乎相当清楚,但我不知道您的示例代码是如何直接应用的。
如果您要创建一个向导,您想要更改正在应用向导步骤的对象,那么在最后一刻之前您不应该实际创建实例。如果直到稍后才创建实例,则问题将变为如何应用向导步骤。但这很容易。
您需要做的是创建List<Action<Animal>> actions
,然后在创建Animal
实例时,您只需运行列表并将操作应用于新实例。如果您更改实例,则只需重新运行列表。
var animal = new Cat();
foreach (var action in actions)
{
action(animal);
}
这有帮助吗?