6

Aという名前の1つの抽象クラスと、Aを実装する他のクラス(B、C、D、Eなど)があります

A オブジェクトのリストもあります。
そのリスト内の各オブジェクトを動的に「基本」型 (B、C、D など) にキャストして、他のメソッドでコンストラクターを呼び出せるようにしたいと考えています。

これが私が今やったことです:

abstract class A { }
class B : A { }
class C : A { }
class D : A { }
class E : A { }
// ... 

class Program
{
    static void Main(string[] args)
    {
        List<A> list = new List<A> { new B(), new C(), new D(), new E() };
        // ...

        foreach (A item in list)
        {
            A obj  = foo(item);
        }
    }

    public static A foo(A obj)
    {
        if (obj.GetType() == typeof(B))
        {
            return bar((B)obj);
        }
        else if (obj.GetType() == typeof(C))
        {
            return bar((C)obj);
        }
        // ... same for D, E, ...
        return null;
    }

    public static T bar<T>(T obj) where T : class, new()
    {
        // To use the constructor, I can't have here an abstract class.
        T newObj = new T();
        return newObj;
    }

それは機能しますが、別の方法を見つけたいのですが、 A を実装する各クラスの型がオブジェクトの型と等しいかどうかをテストし、後でキャストします。

私は B、C、D などのクラスを 15 近く持っています。シンプルで明快で保守しやすいものにするために、このメソッドと 15 以上の "if(...) else(...)" を避けたいと思います。

そうする方法が見えますか?

4

1 に答える 1

10

次のように変更barします。

public static T bar<T>(T obj) where T : class
{
    var type = obj.GetType();
    return Activator.CreateInstance(type) as T;
}

次に変更しfooます:

public static A foo(A obj)
{
    return bar(obj);
}

new()制約を削除する必要があることに注意してください。objの内部をキャストしないようにするために、これを行う必要がありfooました。ただし、型にパラメーターなしのコンストラクターがあるかどうかは、実行時に確認できます。

于 2013-01-14T15:06:31.350 に答える