1

代码:

abstract class Parent{
    void changeChild(){

    }
}
class Child1: Parent{
}
class Child2: Parent{
}
//-----
Parent parent = new Child1(); //instantiated as Child1
parent.changeChild(); //change type of this class to Child2

所以 parent 应该是 Child2 类的实例。

我知道 Child1 可能与 Child2 不同(更多/更少的字段、方法),但我只想在这个对象上调用构造函数,这是不允许的。

简单的

parent = new Child2();

可以完成,但是有 10 个子类(正在增长),我想把它移到父类中

这在 c# 中可能吗?

谢谢

4

6 回答 6

1

您不能更改现有对象的类型,但可以创建一个新对象并将其返回。

例子:

abstract class Parent{

  Parent ChangeChild<T>() where T : Parent {
    if (typeof(T) == typeof(Child1)) {
      return new Child1(this);
    if (typeof(T) == typeof(Child2)) {
      return new Child2(this);
    } else {
      throw new NotImplementedException("Unhandled type");
    }
  }

}

class Child1: Parent{
  public Child1() {} // create
  public Child1(Parent source) {} // convert
}

class Child2: Parent{
  public Child2() {} // create
  public Child2(Parent source) {} // convert
}

Parent parent = new Child1();
parent = parent.ChangeChild<Child2>();
于 2012-04-19T12:28:45.967 回答
0

好吧,如果你只想自动调用那个ctor,应该足以写一些东西,比如

class Child1: Child2{
}

class Child2: Parent{
}

所以你有ctor 在构造Child2时将被调用。Child1但如果是你的,它是完全不同的架构设计。

如果这不是您要的东西,请澄清。

于 2012-04-19T12:22:20.207 回答
0

Automapper 可能是您最好的选择。

T changeChild<T>() : Parent{
   // change the type here.
}
于 2012-04-19T12:23:05.820 回答
0

像这样的东西会起作用吗?

abstract class Parent {
    private Parent Proxy;
    public void ChangeChild<T>() where T : Parent, new() {
        Proxy = new T();
    }
}

您必须使用该Proxy对象来调用成员和属性。

于 2012-04-19T12:27:14.290 回答
0

你不能这样做。也许你可以创建Parent一个包装类

class Parent
{
    Parent _child;

    public Parent(Parent child)
    {
        _child = child;
    }

    public void ChangeChild(Parent child)
    {
        _child = child;
    }

    public string AProperty {
        get { return _child.AProperty; }
        set { _child.AProperty = value; }
    }

    public int AMethod(int x)
    {
        return _child.AMethod(x);
    }
}

进而

Parent parent = new Parent(new Child1());
parent.AProperty = "hello";
int y = parent.AMethod(55);

parent.ChangeChild(new Child2());

注意:父母不应该了解良好的 OO 设计中的特定子项。这确保您可以在以后(例如Child3)创建新子代而无需更改Parent

但是,如果这对您来说不是问题,并且您希望父级自动关心更改子级,则更改或重载构造函数

    public Parent()
    {
        _child = new Child1();
    }

ChangeChild并改变或超载

    public void ChangeChild()
    {
       if (_child is Child1) {
           _child = new Child2();
       } else {
           _child = new Child1();
       }
    }
于 2012-04-19T12:35:02.697 回答
0

如果您需要在运行时更改某些对象的类型,则不需要继承。你应该在这里使用组合。尝试类似策略(如果Parent类代表某种行为)。

public class Foo
{
    // provide default value (or inject it via ctor)
    private Parent _parent = new Child1(); 

    public void ChangeChild(Parent parent){
        _parent = parent;
    }

    public void Bar()
    {
        _parent.DoSomething();  
    }
}

public abstract class Parent
{
    public abstract void DoSomething();
}

public class Child1: Parent
{
    public override void DoSomething() { ... }
}

public class Child2: Parent
{
    public override void DoSomething() { ... }
}

现在您可以在运行时更改依赖类型:

Foo foo = new Foo(new Child1());
foo.Bar(); // child1 implementation used
foo.ChangeChild(new Child2());
foo.Bar(); // child2 implementation used
于 2012-04-19T12:47:56.133 回答