簡體   English   中英

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

[英]C# change type of child class in parent(abstract) class

碼:

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

因此父級應該是Child2類的實例。

我知道Child1可以不同於Child2(更多/更少的字段,方法),但是我只想在此對象上調用構造函數,這是不允許的。

簡單

parent = new Child2();

可以完成,但是有大約10個子類(正在增長),我想將其移到父類中

在C#中這有可能嗎?

謝謝

您不能更改現有對象的類型,但是可以創建一個新對象並將其返回。

例:

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

好吧,如果您只想自動調用ctor,應該足以使某些東西變形,例如

class Child1: Child2{
}

class Child2: Parent{
}

所以,你必須Child2構造函數時,將調用Child1構造。 但是就您而言,這是完全不同的體系結構設計。

如果不是您要的東西,請澄清一下。

Automapper可能是您最好的選擇。

T changeChild<T>() : Parent{
   // change the type here.
}

這樣的事情行嗎?

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

您必須使用Proxy對象來調用成員和屬性。

你不能這樣做。 也許您可以將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();
       }
    }

如果需要在運行時更改某些對象的類型,則繼承不是這種情況。 您應該在這里使用合成。 嘗試類似策略 (如果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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM