Bisakah seseorang menjelaskan Activator.CreateInstance()
tujuan secara rinci?
c#.net
cara melakukannya Object xyz = Class.forName(className).newInstance();
.
Bisakah seseorang menjelaskan Activator.CreateInstance()
tujuan secara rinci?
c#.net
cara melakukannya Object xyz = Class.forName(className).newInstance();
.
Jawaban:
Katakanlah Anda memiliki kelas yang disebut MyFancyObject
seperti ini di bawah ini:
class MyFancyObject
{
public int A { get;set;}
}
Ini memungkinkan Anda mengubah:
String ClassName = "MyFancyObject";
Ke
MyFancyObject obj;
Menggunakan
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
dan kemudian dapat melakukan hal-hal seperti:
obj.A = 100;
Itulah tujuannya. Ini juga memiliki banyak kelebihan lainnya seperti memberikan sebagai Type
ganti nama kelas dalam sebuah string. Mengapa Anda mengalami masalah seperti itu adalah cerita yang berbeda. Inilah beberapa orang yang membutuhkannya:
String ClassName = "My.Namespace.MyFancyObject";
).
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
tetapi alih-alih melakukan casting dengan tipe tersebut. Transmisikan dengan tipe yang terbuat dari ClassName? Seperti ini Type type = Type.GetType(ClassName);obj = (type )Activator.CreateInstance("MyAssembly", ClassName))
?
Saya bisa memberikan contoh mengapa menggunakan sesuatu seperti itu. Pikirkan game di mana Anda ingin menyimpan level dan musuh Anda dalam file XML. Saat Anda mengurai file ini, Anda mungkin memiliki elemen seperti ini.
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
apa yang dapat Anda lakukan sekarang adalah, membuat objek yang ditemukan di file level Anda secara dinamis.
foreach(XmlNode node in doc)
var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
Ini sangat berguna, untuk membangun lingkungan yang dinamis. Tentu saja juga memungkinkan untuk menggunakan ini untuk skenario Plugin atau addin dan banyak lagi.
Teman baik saya MSDN dapat menjelaskannya kepada Anda, dengan sebuah contoh
Berikut adalah kode jika tautan atau konten berubah di masa mendatang:
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
Anda juga bisa melakukan ini -
var handle = Activator.CreateInstance("AssemblyName",
"Full name of the class including the namespace and class name");
var obj = handle.Unwrap();
.Unwrap()
tepatnya dan bagaimana hal ini berkaitan dengan solusi lain?
CreateInstance
mana ia kembali System.Runtime.Remoting.ObjectHandle
.
Contoh yang baik adalah yang berikutnya: misalnya Anda memiliki sekumpulan Logger dan Anda mengizinkan pengguna untuk menentukan jenis yang akan digunakan dalam runtime melalui file konfigurasi.
Kemudian:
string rawLoggerType = configurationService.GetLoggerType();
Type loggerType = Type.GetType(rawLoggerType);
ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
ATAU kasus lainnya adalah ketika Anda memiliki pabrik entitas umum, yang membuat entitas, dan juga bertanggung jawab atas inisialisasi entitas dengan data yang diterima dari DB:
(pseudocode)
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)
mengakibatkanloggerType is a variable and used like a type
Itu Activator.CreateInstance
Metode menciptakan sebuah instance dari tipe tertentu menggunakan konstruktor yang paling cocok dengan parameter yang ditentukan.
Misalnya, Anda memiliki nama tipe sebagai string, dan Anda ingin menggunakan string untuk membuat instance dari tipe itu. Anda bisa menggunakan Activator.CreateInstance
untuk ini:
string objTypeName = "Foo";
Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
Berikut artikel MSDN yang menjelaskan aplikasinya secara lebih rinci:
new Foo()
. Saya pikir OP menginginkan contoh yang lebih realistis.
CreateInstance
adalah jika Anda tidak mengetahui jenis objek yang akan Anda buat pada waktu desain. Dalam contoh ini, Anda mengetahui dengan jelas jenisnya Foo
karena Anda mentransmisikannya sebagai jenis Foo
. Anda tidak akan pernah melakukan ini karena Anda bisa melakukannya Foo foo = new Foo()
.
Membangun dari deepee1 dan ini , berikut ini cara menerima nama kelas dalam string, dan kemudian menggunakannya untuk membaca dan menulis ke database dengan LINQ. Saya menggunakan "dinamis" daripada casting deepee1 karena memungkinkan saya untuk menetapkan properti, yang memungkinkan kita untuk secara dinamis memilih dan beroperasi pada tabel yang kita inginkan.
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);
Mengapa Anda menggunakannya jika Anda sudah mengetahui kelas tersebut dan akan menayangkannya? Mengapa tidak melakukannya dengan cara lama dan membuat kelas seperti Anda selalu membuatnya? Tidak ada keuntungan untuk ini dibandingkan dengan cara yang biasa dilakukan. Adakah cara untuk mengambil teks dan mengoperasikannya sebagai berikut:
label1.txt = "Pizza"
Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);
p.method1();
p.method2();
Jika saya sudah tahu ini adalah Pizza, tidak ada keuntungan untuk:
p = (Pizza)somefancyjunk("Pizza"); over
Pizza p = new Pizza();
tetapi saya melihat keuntungan besar pada metode Sihir jika itu ada.
Ditambah dengan refleksi, saya menemukan Activator.CreateInstance sangat membantu dalam memetakan hasil prosedur tersimpan ke kelas khusus seperti yang dijelaskan dalam jawaban berikut .
CreateInstance(Type type)
cocok denganCreateInstance<T>()
kelebihan beban.