C#更改父(抽象)类中子类的类型

C#更改父(抽象)类中子类的类型,c#,inheritance,C#,Inheritance,代码: 所以父类应该是Child2类的实例 我理解Child1可以不同于Child2(更多/更少字段、方法), 但我只想对这个对象调用构造函数,这是不允许的 简单的 abstract class Parent{ void changeChild(){ } } class Child1: Parent{ } class Child2: Parent{ } //----- Parent parent = new Child1(); //instantiated as Child1

代码:

所以父类应该是Child2类的实例

我理解Child1可以不同于Child2(更多/更少字段、方法), 但我只想对这个对象调用构造函数,这是不允许的

简单的

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
可以这样做,但有大约10个子类(正在增长),我想把它转移到父类中

这在c#中可能吗


谢谢

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

parent = new Child2();
因此,当构造
Child1
时,将调用
Child2
ctor。但这是完全不同的建筑设计,如果你的


如果不是你想要的东西,请澄清。

好吧,如果你想要的只是自动调用ctor,应该足以编写一些东西,比如

parent = new Child2();
因此,当构造
Child1
时,将调用
Child2
ctor。但这是完全不同的建筑设计,如果你的


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

Automapper可能是你最好的选择

class Child1: Child2{
}

class Child2: Parent{
}
T changeChild():父项{
//在这里更改类型。
}

Automapper可能是您的最佳选择

class Child1: Child2{
}

class Child2: Parent{
}
T changeChild():父项{
//在这里更改类型。
}

您喜欢这项工作吗

T changeChild<T>() : Parent{
   // change the type here.
}
抽象类父类{
私人家长代理;
public void ChangeChild(),其中T:Parent,new(){
Proxy=newt();
}
}

您必须使用
代理
对象来调用成员和属性。

是否需要此工作

T changeChild<T>() : Parent{
   // change the type here.
}
抽象类父类{
私人家长代理;
public void ChangeChild(),其中T:Parent,new(){
Proxy=newt();
}
}

您必须使用代理对象调用成员和属性。

您不能更改现有对象的类型,但可以创建新对象并返回它

例如:

abstract class Parent {
    private Parent Proxy;
    public void ChangeChild<T>() where T : Parent, new() {
        Proxy = new T();
    }
}
抽象类父类{
父ChangeChild(),其中T:Parent{
if(typeof(T)=typeof(Child1)){
归还新子女1(本);
if(typeof(T)=typeof(Child2)){
归还新子女2(本);
}否则{
抛出新的NotImplementedException(“未处理类型”);
}
}
}
第1类:家长{
public Child1(){}//创建
公共Child1(父源){}//convert
}
第2类:家长{
public Child2(){}//创建
公共Child2(父源){}//convert
}
父项=新的子项1();
parent=parent.ChangeChild();

您不能更改现有对象的类型,但可以创建新对象并返回它

例如:

abstract class Parent {
    private Parent Proxy;
    public void ChangeChild<T>() where T : Parent, new() {
        Proxy = new T();
    }
}
抽象类父类{
父ChangeChild(),其中T:Parent{
if(typeof(T)=typeof(Child1)){
归还新子女1(本);
if(typeof(T)=typeof(Child2)){
归还新子女2(本);
}否则{
抛出新的NotImplementedException(“未处理类型”);
}
}
}
第1类:家长{
public Child1(){}//创建
公共Child1(父源){}//convert
}
第2类:家长{
public Child2(){}//创建
公共Child2(父源){}//convert
}
父项=新的子项1();
parent=parent.ChangeChild();

您不能这样做。也许您可以创建
父类作为包装类

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>();
然后

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

注意:在一个好的OO设计中,父对象不应该知道特定的子对象。这可以确保您以后可以创建新的子对象(例如
Child3
),而无需更改
parent

但是,如果这不是您的问题,并且您希望父级自动关心更改子级,则使用

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

parent.ChangeChild(new Child2());
并使用

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

您不能这样做。也许您可以创建
Parent
作为包装类

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>();
然后

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

注意:在一个好的OO设计中,父对象不应该知道特定的子对象。这可以确保您以后可以创建新的子对象(例如
Child3
),而无需更改
parent

但是,如果这不是您的问题,并且您希望父级自动关心更改子级,则使用

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

parent.ChangeChild(new Child2());
并使用

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

若您需要在运行时更改某个对象的类型,则不需要继承。您应该在此处使用组合。请尝试类似的操作(若
Parent
class代表某些行为)

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

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() { ... }
}

若您需要在运行时更改某个对象的类型,则不需要继承。您应该在此处使用组合。请尝试类似的操作(若
Parent
class代表某些行为)

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

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() { ... }
}

谢谢,但这不符合我项目的OOP思维,例如parent=Dog,child1=Husky,child2=whatewer类型的狗谢谢,但这不符合我项目的OOP思维,例如parent=Dog,child1=Husky,child2=whatewer类型的狗你可以简化它。首先将
new()
约束添加到
t
parent ChangeChild()其中T:Parent,new()
。然后您可以使用
new T()创建一个新的子级
@OlivierJacot Descombes:是的,这是一个选项,但是您不能将当前对象发送给构造函数,因此您需要一个抽象方法来填充该对象。是的;但是该方法可以得到保护,因此不会影响
父对象的公共接口。
。此外,新派生时不需要更改父对象引入了d类。您可以对此进行简化。首先将
new()
约束添加到
T
Parent ChangeChild(),其中T:Parent,new()
。然后您可以使用
new T()
@OlivierJacot Descombes创建一个新的子级