0

私は次のような継承ツリーを持っています:

BaseType
TypeA : BaseType
TypeB : BaseType
TypeC : BaseType

各派生オブジェクトには、objectNameそのオブジェクトの名前を定義する名前付き変数があります。

BaseTypeまた、オブジェクトと から派生したオブジェクトを保持する配列とリストもありますBaseType。配列には、作成時にオブジェクトが格納されていますが、リストは将来の使用のために空です。

BaseType[] arrayA = new BaseType[] { new TypeA(), new TypeB(), new TypeC(), }

List<BaseType> listA = new List<BaseType>;

配列内のオブジェクトをリストに追加するために使用するメソッドもあります。

public void AddToList(BaseType itemToAdd)
{
    if(itemToAdd.objectName == "Type A")
        {
        listA.Add(new TypeA());
    }
    else if(itemToAdd.objectName == "Type B")
        {
        listA.Add(new TypeB());
    }
    else if(itemToAdd.objectName == "Type C")
        {
        listA.Add(new TypeA());
    }
}

ifこれらのコマンドをすべて使用する必要がないようにするにはどうすればよいですか? ある時点で私は試しました:

public void AddToList(BaseType itemToAdd)
{
    listA.Add( new itemToAdd());
}

うまくいきませんでした。では、どうすればこのようなことを行うことができますか? ifオブジェクトは常に成長しており、追加する派生オブジェクトごとに forを配置する必要はありません。また、これがソリューションに関係するかどうかはわかりませんが、フォルダーを使用して .cs ファイルを整理しています。したがって、「Types」という名前のフォルダーにすべての派生クラスがあるため、そのオブジェクトの新しいインスタンスを作成するには、次のように入力する必要があります。

listA.Add(new Types.TypeA());
4

3 に答える 3

2

最初に目にしたのは、アイテムを渡すだけでなく、アイテムをインスタンス化していることです

次のことをしようとしていますか?

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd);
}


理由

public void AddToList(BaseType itemToAdd)
{
    listA.Add( new itemToAdd());
}

itemToAddはタイプではなく、タイプの変数であるため、機能しませんBaseTypenewキーワードを使用することはできません。意味がありません。


アイテムをコピーしようとしている場合は、次のようなことができます。

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd.Copy());
}

この部分を機能させるには、独自のコピー メソッドを作成する必要があります。

于 2012-11-05T19:40:07.443 に答える
1

AddToList が itemToAdd を追加するのではなく、新しいオブジェクトを作成するのはなぜですか? 言い換えると:

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd);
}

また、オブジェクトのタイプに文字列を指定する必要はありません。以下を使用して、任意のオブジェクトのタイプを取得できます。

myObj.GetType();

また、次を使用してオブジェクトのタイプを比較できますtypeof

if (myObj.GetType() == typeof(TypeA))

と同じタイプの新しいオブジェクトを本当に作成する必要がある場合itemToAddは、 を使用Activator.CreateInstanceしてこれらすべてのタイプ チェックを回避できます。

listA.Add((BaseType)Activator.CreateInstance(itemToAdd.GetType());

しかし、とにかくそれはあなたがやりたいことではないと思います。

于 2012-11-05T19:41:02.783 に答える
0

さて、渡されたクラスタイプに基づいて必要なオブジェクトを作成するクラスへのファクトリを作成し、次のように使用できます。

public void AddToList(BaseType itemToAdd)
{
    listA.Add(ItemFactory.Create(itemToAdd.objectName));
}

もちろん、これは質問を 1 レベル下げるだけです (ただし、AddToList コードの読みやすさは向上します)。

あなたが本当に求めていることを行うには、あなたがすでに提案したことを行う必要があると思います.if-elseチェーン(またはおそらくスイッチ)で正しいタイプのインスタンスを作成します。またはリフレクションを使用して、動的に選択されたクラスのインスタンスを新しく作成します。

簡単な例として:

BaseType Create(BaseType source)
{
    var constructor = source.GetType().GetConstructor(new Type[0]);
    return constructor.Invoke(new object[0]) as BaseType;
}
于 2012-11-05T19:47:25.950 に答える