简体   繁体   English

C#对象实例化问题

[英]C# Object Instantiation Question

I would appreciate some help refactoring my code. 我希望能对重构我的代码有所帮助。 If I pass an instance of an object to another object instance is there any way to reinstantiate that instance without losing the reference? 如果我将一个对象的实例传递给另一个对象的实例,是否可以在不丢失引用的情况下重新实例化该实例?

Here is a simplified version of the problem I have: 这是我遇到的问题的简化版本:

    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";
    }
}

Can myPet.Fleas = 100 in Program after calling GetNewPet()? 调用GetNewPet()后,程序中的myPet.Fleas = 100可以吗?

If I want to change the underlying type of object instance can I do that? 如果我想更改对象实例的基础类型,可以这样做吗? If not, does anyone have any refactoring suggestions? 如果没有,是否有人提出任何重构建议?

I will try and describe the details of the actual program structure. 我将尝试描述实际程序结构的细节。

I am creating a WPF Wizard. 我正在创建一个WPF向导。

That Wizard has steps. 该向导具有步骤。

When I start the Wizard an instance of the WizardViewModel class is created. 当我启动向导时,将创建WizardViewModel类的实例。

WizardViewModel class has an instance of ObjectX (an object whoes properties I want to modify and then return the object when the wizard is complete). WizardViewModel类具有ObjectX的实例(我想要修改其属性的对象,然后在向导完成后返回该对象)。

Each step in the wizard is an instance of the WizardPageViewModelBase class which is passed an instance of ObjectX in the constructor. 向导中的每个步骤都是WizardPageViewModelBase类的实例,该类在构造函数中传递给ObjectX实例。

WizardViewModel has a list of WizardPageViewModelBase objects (one object instance for each wizard step). WizardViewModel具有WizardPageViewModelBase对象的列表(每个向导步骤一个对象实例)。

So as long as I am only changing the properties of the ObjectX instance in each wizard step (WizardPageViewModelBase object instance) then the object that is returned by WizardViewModel works fine. 因此,只要我仅在每个向导步骤(WizardPageViewModelBase对象实例)中更改ObjectX实例的属性,那么WizardViewModel返回的对象就可以正常工作。

However in step 1 of the wizard I want to change the underlying type of ObjectX depending on what the user selects from a listbox. 但是,在向导的第1步中,我想根据用户从列表框中选择的内容来更改ObjectX的基础类型。 If I change the instance (as I do in GetNewPet() above) the reference to the ObjectX instance in WizardViewModel is lost. 如果更改实例(如我在上面的GetNewPet()中所做的那样),则对WizardViewModel中的ObjectX实例的引用将丢失。

Apologies if this makes no sense, I tried my best to structure the question in a way that can be answered... 抱歉,如果这没有任何意义,我会尽力以一种可以回答的方式来构造问题。

You're never using the House's pet. 您从不使用房屋的宠物。

Even though you call myHouse.GetNewPet() which effectively replaces the CurrentPet of myHouse, it doesn't matter because you're never using Current Pet. 即使您调用myHouse.GetNewPet()可以有效替换myHouse的CurrentPet,也没关系,因为您从未使用过Current Pet。

Your main program only uses myPet, which is always the Cat you created at the beginning. 您的主程序仅使用myPet,它始终是您一开始创建的Cat。

So, in effect, your problem isn't that you're losing a reference to an Animal, it's that you never gave up the reference to begin with. 因此,实际上,您的问题不是您丢失了对Animal的引用,而是您从未放弃过对它的引用。

I imagine what you're intending to do is something to the effect of: 我想您打算做的事情会产生以下效果:

Console.WriteLine(String.Format("My pet has {0} flea(s)", 
    myHouse.CurrentPet.Fleas.ToString()));

With the following code, where _fleas is made static, I can get "My pet has 100 flea(s)" but am not sure if that 's what you want: 使用以下代码,将_fleas设为静态,我可以得到“我的宠物有100条跳蚤”,但是不确定这是否是您想要的:

public abstract class Animal
    {

        static int _fleas;

        public int Fleas
        {
            get { return _fleas; }
            set { _fleas = value; }
        }

        public abstract string GetSound();

    }

The description of your problem seems reasonably clear, but I don't see how your sample code directly applies. 您的问题的描述似乎很清楚,但是我看不到您的示例代码是如何直接应用的。

If you're creating a wizard where you want to change the object that you're applying the steps of the wizard on then you shouldn't actually create the instance until the last moment. 如果要在创建向导时要更改应用向导步骤的对象,那么直到最后一刻才真正创建实例。 The issue becomes how to apply the wizard steps if you don't create the instance until later. 如果您直到稍后才创建实例,问题就变成如何应用向导步骤。 But that's easy. 但这很容易。

What you need to do is to create a List<Action<Animal>> actions and then when you create the Animal instance you just run through the list and apply the action to the new instance. 您需要做的是创建一个List<Action<Animal>> actions ,然后在创建Animal实例时,您只需在列表中运行并将该动作应用于新实例。 If you change the instance you just re-run the list. 如果更改实例,则只需重新运行列表即可。

var animal = new Cat();
foreach (var action in actions)
{
    action(animal);
}

Does this help? 这有帮助吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM