2009-02-23 22 views
37

私のデータベースには、アプリケーション全体の関係を管理するためのテーブルがあります。親の型、parentId、childType、childId ...のすべてがintとしてかなり自然です。前にこの設定を行ったことがありますが、私は6つの異なるテーブルをリンクしようとしていたときにスイッチ/ケースの設定でそれを行いました。今私はこれをやろうとしている30のテーブルを持っています。私はswitchコマンドに30個のcaseエントリーを書く必要なしにこれを行うことができます。オブジェクトを動的に作成<Type>

文字列を使用して.NETクラスへの参照を作成する方法はありますか?私は(私はこれにはいくつかのバリエーションを試してみたので)、これは有効ではありません知っている:

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

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

答えて

49

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

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)); 
} 
+2

タイプを含むアセンブリがAppDomainにまだロードされていない場合、これは機能しません。 –

+3

また、そのメソッドを呼び出すためには、OPはコンパイル時に型にアクセスできる必要があります。元の質問は、実行時に文字列からインスタンスを作成する方法を尋ねました。 –

+0

私は単に質問に記載されている例に基づいて私の答えに基づいています。 –

9

あなたが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(); 
    } 
} 
11

タイプは、発信者によって知られている場合は、Activator.CreateInstanceを使用してより良い、より高速な方法があります:あなたの代わりに、一般的な制約を使用することができますこのメソッドは、デフォルトのパラメータのないコンストラクタを持っています。

このようにすることは、型セーフであり、リフレクションを必要としません。

T CreateType<T>() where T : new() 
{ 
    return new T(); 
} 
+6

ソースコードレベルでのリフレクションは必要ありません。生成されたILでもActivator.CreateInstanceが使用されます。 –

+1

文字列を使用して指定されたOPがタイプを識別するため、反射が必要です。 –

0

あなたは以下の型持っていると仮定:

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); 
8
public static T GetInstance<T>(params object[] args) 
{ 
    return (T)Activator.CreateInstance(typeof(T), args); 
} 

私はActivator.CreateInstance()を、キャストの代わりにActivator hジェネリックのためのコンストラクタとして。

1

これは、リフレクションを使用して、タイプ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; 
    } 

非常に単純な実装である、私は複雑なタイプを処理しませんでした。

Assaf