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

したがって、親は 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

このようなものは機能しますか?

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

実行時に一部のオブジェクトのタイプを変更する必要がある場合、継承は当てはまりません。ここではコンポジションを使用する必要があります。Strategyのようなものを試してください(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 に答える
0

まあ、その ctor が自動的に呼び出されることだけが必要な場合は、次のようなものを書き込むだけで十分です。

class Child1: Child2{
}

class Child2: Parent{
}

したがって、構築Child2時に呼び出されるctorがありますChild1。しかし、あなたのものであれば、それは完全に異なるアーキテクチャ設計です。

それがあなたが求めているものでない場合は、明確にしてください。

于 2012-04-19T12:22:20.207 に答える
0

Automapper が最善の策かもしれません。

T changeChild<T>() : Parent{
   // change the type here.
}
于 2012-04-19T12:23:05.820 に答える
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 に答える