web-dev-qa-db-ja.com

<Type>のオブジェクトを動的に作成します

データベース内に、アプリケーション全体の関係を管理するために使用するテーブルがあります。それは本質的にかなり基本的です-parentType、parentId、childType、childId ... intとしてすべて。以前にこのセットアップを行ったことがありますが、リンクしようとしていた6つの異なるテーブルがあったときに、スイッチ/ケースのセットアップを行いました。これで、これを実行しようとしている30個のテーブルがあり、switchコマンドに30個のケースエントリを書き込む必要なく、これを実行できるようになりたいと思います。

文字列を使用して.Netクラスを参照する方法はありますか?私はこれが無効であることを知っています(これのいくつかのバリエーションを試したため):

Type t = Type.GetType("WebCore.Models.Page");
object page = new t();

オブジェクトのタイプを取得する方法は知っていますが、それをその場で使用して新しいオブジェクトを作成するにはどうすればよいですか?

42
thaBadDawg

このリンクは役立つはずです:

http://msdn.Microsoft.com/en-us/library/system.activator.createinstance(VS.71).aspx

Activator.CreateInstanceは、指定されたタイプのインスタンスを作成します。

これを次のような一般的なメソッドでラップできます。

public T GetInstance<T>(string type)
{
    return (T)Activator.CreateInstance(Type.GetType(type));
}
57

呼び出し元が型を知っている場合は、Activator.CreateInstanceを使用するよりも優れた高速な方法があります。代わりに、デフォルトのパラメーターレスコンストラクターを指定するメソッドに汎用制約を使用できます。

この方法で行うことはタイプセーフであり、リフレクションを必要としません。

T CreateType<T>() where T : new()
{
   return new T();
}
13
public static T GetInstance<T>(params object[] args)
{
     return (T)Activator.CreateInstance(typeof(T), args);
}

アクティベーターにはジェネリックのコンストラクターがあるため、キャストの代わりにActivator.CreateInstance()を使用します。

10
AmuuuInjured

使用したい Activator.CreateInstance

次に、その仕組みの例を示します。

using System;
using System.Runtime.Remoting;

class Program
{
    static void Main()
    {
        ObjectHandle o = Activator.CreateInstance("mscorlib.dll", "System.Int32");

        Int32 i = (Int32)o.Unwrap();
    }
}
9
Andrew Hare

ここに、リフレクションを使用してT型のレコードを複製する関数を記述しました。これは非常に単純な実装であり、複雑な型などは処理しませんでした。

 public static T Clone<T>(T original)
    {
        T newObject = (T)Activator.CreateInstance(original.GetType());

        foreach (var prop in original.GetType().GetProperties())
        {
            prop.SetValue(newObject, prop.GetValue(original));
        }

        return newObject;
    }

これが誰かを助けることを願っています。

アサフ

1
Assaf S.

次のタイプがあると仮定します。

public class Counter<T>
{
  public T Value { get; set; }
}

型のアセンブリ修飾名がある場合、次の方法で構築できます。

string typeName = typeof(Counter<>).AssemblyQualifiedName;
Type t = Type.GetType(typeName);

Counter<int> counter = 
  (Counter<int>)Activator.CreateInstance(
    t.MakeGenericType(typeof(int)));

counter.Value++;
Console.WriteLine(counter.Value);
0
sduplooy