3

抽象クラスから継承するクラスが一定量あります。

abstract public class baseClass
{
    //logics
}

public class child1 : baseClass
{
}

public class child2 : baseClass
{
}

これで、次のように同じ名前の値を持つ列挙型に応じて、これらのクラスの1つを作成する必要がある管理クラスがいくつかあります。

public enum ClassType
{
    child1,
    child2
}

public class Manager
{
    private List<baseClass> _workers;

    public void Initialize(ClassType type)
    {
        //what logics to put here? (resulting in correctChild)
        _workers.Add(correctChild);
    }
}

typeofを考えていましたが、実装方法がよくわかりません。注:この例では2つのクラスですが、実際には任意の数のクラスです。

4

4 に答える 4

6

Activator.CreateInstance()を見てください

名前付きアセンブリとデフォルトのコンストラクターを使用して、名前が指定されたタイプのインスタンスを作成します。

したがって、コードは次のようになります

Activator.CreateInstance(type.ToString(),assemblyName);

私は実際にそのような実装に精通しており、私はそれを自分で使用しました。また、列挙値の属性を実際に使用して実際のクラス名を格納する方法を説明しているこの記事を調べることをお勧めします。拡張機能として使用することもできます。

 public static string Description(this Enum enumValue) {
        Type enumType = enumValue.GetType();
        FieldInfo field = enumType.GetField(enumValue.ToString());
        object[] attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length == 0 ? enumValue.ToString() : ((DescriptionAttribute)attributes[0]).Description;
}

コードは次のようになります

Activator.CreateInstance(classType.Description(), assemblyName);
于 2013-03-16T16:42:20.873 に答える
1

属性のオーバーヘッドが不要で、同じアセンブリからこれを実行している場合は、実行中のアセンブリを使用して、リフレクションを介して型をロードできます。Activator.CreateInstance動的にオブジェクトを構築することができます。

public class Manager
{
    private List<baseClass> _workers = new List<baseClass>();

    public void Initialize(ClassType type)
    {
        string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
        Type objType = Type.GetType(string.Format("{0}.{1},{0}", assemblyName, type.ToString()));
        var correctChild =  (baseClass)Activator.CreateInstance(objType);
        _workers.Add(correctChild);
    }
}
于 2013-03-16T16:53:32.870 に答える
0

タイプを区別する方法はたくさんあります。

is演算子を使用できます

var o = ...;
if (o is Child1) {}

asまたは、演算子を使用できます

var child = o as Child1;
if (child != null) {}

またはあなたがすでにあなた自身を説明したこと、typeofオペレーター。

しかし、私が感じているのは、型キャストが強く必要な場合は、何か他のものが手元にあるかもしれないということです。多分あなたはポリモーフィズムによってあなたの問題を解決することができます。if-elseそうすれば、longまたは構文のすべての異なるタイプを区別する必要はありませんがcase-switch、「異なる動作」をサブクラスに委任することができます。

于 2013-03-16T16:36:47.367 に答える
0

ifステートメントを使用したくない場合は、caseステートメントを使用できますか?お気に入り:

public class Manager
{
    private List<baseClass> _workers;

    public void Initialize(ClassType type)
    {
        switch (type)
        {
            case child1:
              _workers.Add(correctChild);
              break;
            case child2:
              _workers.Add(correctChild);
              break;
        }
    }
}
于 2013-03-16T16:39:56.667 に答える