C#对象实例化问题

时间:2011-08-23 12:05:37

标签: c#

我很感激帮助重构我的代码。如果我将一个对象的实例传递给另一个对象实例,有没有办法重新实例化该实例而不会丢失引用?

以下是我遇到的问题的简化版本:

    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实例的引用。

道歉,如果这没有意义,我尽力以可以回答的方式构建问题......

3 个答案:

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

这有帮助吗?