誰かがActivator.CreateInstance()
目的を詳細に説明できますか?
c#.net
方法ですObject xyz = Class.forName(className).newInstance();
。
誰かがActivator.CreateInstance()
目的を詳細に説明できますか?
c#.net
方法ですObject xyz = Class.forName(className).newInstance();
。
回答:
MyFancyObject
次のようなクラスがあるとします。
class MyFancyObject
{
public int A { get;set;}
}
次のことが可能になります。
String ClassName = "MyFancyObject";
に
MyFancyObject obj;
使用する
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
そして、次のようなことができます:
obj.A = 100;
それが目的です。Type
文字列でクラス名の代わりにを提供するなど、他にも多くのオーバーロードがあります。なぜあなたがそのような問題を抱えるのかは別の話です。これが必要な人がいます:
String ClassName = "My.Namespace.MyFancyObject";
)に名前空間を含めたことを確認する必要がありました。
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
タイプでキャストする代わりに、このようなことはできますか?ClassNameから作成された型でキャストしますか?このようにType type = Type.GetType(ClassName);obj = (type )Activator.CreateInstance("MyAssembly", ClassName))
?
まあ、そのようなものを使用する理由の例を挙げましょう。レベルと敵をXMLファイルに保存するゲームを考えてみてください。このファイルを解析すると、次のような要素がある場合があります。
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
ここでできることは、レベルファイルで見つかったオブジェクトを動的に作成することです。
foreach(XmlNode node in doc)
var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
これは、動的な環境を構築するのに非常に役立ちます。もちろん、これをプラグインやアドインのシナリオなどで使用することもできます。
私の親友のMSDN が例を挙げて説明します
リンクまたはコンテンツが将来変更される場合のコードは次のとおりです。
using System;
class DynamicInstanceList
{
private static string instanceSpec = "System.EventArgs;System.Random;" +
"System.Exception;System.Object;System.Version";
public static void Main()
{
string[] instances = instanceSpec.Split(';');
Array instlist = Array.CreateInstance(typeof(object), instances.Length);
object item;
for (int i = 0; i < instances.Length; i++)
{
// create the object from the specification string
Console.WriteLine("Creating instance of: {0}", instances[i]);
item = Activator.CreateInstance(Type.GetType(instances[i]));
instlist.SetValue(item, i);
}
Console.WriteLine("\nObjects and their default values:\n");
foreach (object o in instlist)
{
Console.WriteLine("Type: {0}\nValue: {1}\nHashCode: {2}\n",
o.GetType().FullName, o.ToString(), o.GetHashCode());
}
}
}
// This program will display output similar to the following:
//
// Creating instance of: System.EventArgs
// Creating instance of: System.Random
// Creating instance of: System.Exception
// Creating instance of: System.Object
// Creating instance of: System.Version
//
// Objects and their default values:
//
// Type: System.EventArgs
// Value: System.EventArgs
// HashCode: 46104728
//
// Type: System.Random
// Value: System.Random
// HashCode: 12289376
//
// Type: System.Exception
// Value: System.Exception: Exception of type 'System.Exception' was thrown.
// HashCode: 55530882
//
// Type: System.Object
// Value: System.Object
// HashCode: 30015890
//
// Type: System.Version
// Value: 0.0
// HashCode: 1048575
これを行うこともできます-
var handle = Activator.CreateInstance("AssemblyName",
"Full name of the class including the namespace and class name");
var obj = handle.Unwrap();
.Unwrap()
正確には何が行われ、これが他のソリューションとどのように関連するかについて、追加の説明を提供できますか?
CreateInstance
が返す場所の異なるオーバーロードにありますSystem.Runtime.Remoting.ObjectHandle
。
次の例が良い例です。たとえば、ロガーのセットがあり、ユーザーが構成ファイルを介してランタイムで使用するタイプを指定できるようにします。
次に:
string rawLoggerType = configurationService.GetLoggerType();
Type loggerType = Type.GetType(rawLoggerType);
ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
または、別のケースとして、エンティティを作成し、DBから受信したデータによるエンティティの初期化も担当する共通エンティティファクトリがある場合があります。
(疑似コード)
public TEntity CreateEntityFromDataRow<TEntity>(DataRow row)
where TEntity : IDbEntity, class
{
MethodInfo methodInfo = typeof(T).GetMethod("BuildFromDataRow");
TEntity instance = Activator.CreateInstance(typeof(TEntity)) as TEntity;
return methodInfo.Invoke(instance, new object[] { row } ) as TEntity;
}
typeof(loggerType)
結果はloggerType is a variable and used like a type
このActivator.CreateInstance
メソッドは、指定されたパラメーターに最も一致するコンストラクターを使用して、指定された型のインスタンスを作成します。
たとえば、型名が文字列としてあり、その文字列を使用してその型のインスタンスを作成するとします。あなたはActivator.CreateInstance
これに使うことができます:
string objTypeName = "Foo";
Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
アプリケーションについて詳しく説明したMSDNの記事は次のとおりです。
new Foo()
。OPはより現実的な例を望んでいたと思います。
CreateInstance
、設計時にインスタンス化するオブジェクトのタイプがわからない場合です。この例では、type Foo
としてキャストしているので、それがtype であることは明らかですFoo
。あなたはただできるので、あなたはこれを決してすることはないでしょうFoo foo = new Foo()
。
deepee1とthisを基にして、文字列内のクラス名を受け入れ、それを使用してLINQでデータベースの読み取りと書き込みを行う方法を説明します。プロパティを割り当てることができるため、deepee1のキャストの代わりに「動的」を使用します。これにより、必要なテーブルを動的に選択して操作できます。
Type tableType = Assembly.GetExecutingAssembly().GetType("NameSpace.TableName");
ITable itable = dbcontext.GetTable(tableType);
//prints contents of the table
foreach (object y in itable) {
string value = (string)y.GetType().GetProperty("ColumnName").GetValue(y, null);
Console.WriteLine(value);
}
//inserting into a table
dynamic tableClass = Activator.CreateInstance(tableType);
//Alternative to using tableType, using Tony's tips
dynamic tableClass = Activator.CreateInstance(null, "NameSpace.TableName").Unwrap();
tableClass.Word = userParameter;
itable.InsertOnSubmit(tableClass);
dbcontext.SubmitChanges();
//sql equivalent
dbcontext.ExecuteCommand("INSERT INTO [TableNme]([ColumnName]) VALUES ({0})", userParameter);
すでにクラスを知っていて、それをキャストするのであれば、なぜそれを使用するのですか?昔ながらのやり方で、いつものようにクラスを作ってみませんか?これが通常行われている方法に勝る利点はありません。テキストを受け取り、それを操作する方法はありますか?
label1.txt = "Pizza"
Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);
p.method1();
p.method2();
私がすでにそのピザを知っているなら、何の利点もありません:
p = (Pizza)somefancyjunk("Pizza"); over
Pizza p = new Pizza();
しかし、マジックの方法が存在すれば、それが非常に有利だと思います。
CreateInstance(Type type)
と一致させることをお勧めしCreateInstance<T>()
ます。