Can someone explain Activator.CreateInstance()
purpose in detail?
有人能解释一下Activator.CreateInstance()的目的吗?
9 个解决方案
#1
Say you have a class called MyFancyObject
like this one below:
假设您有一个名为MyFancyObject的类,如下所示:
class MyFancyObject{ public int A { get;set;}}
It lets you turn:
它可以让你转:
String ClassName = "MyFancyObject";
Into
MyFancyObject obj;
Using
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
and can then do stuff like:
然后可以做类似的事情:
obj.A = 100;
That's its purpose. It also has many other overloads such as providing a Type
instead of the class name in a string. Why you would have a problem like that is a different story. Here's some people who needed it:
这是它的目的。它还有许多其他重载,例如在字符串中提供Type而不是类名。为什么你会有这样的问题是一个不同的故事。以下是一些需要它的人:
- Createinstance() - Am I doing this right?
- C# Using Activator.CreateInstance
- Creating an object without knowing the class name at design time
Createinstance() - 我这样做了吗?
C#使用Activator.CreateInstance
在设计时不知道类名创建对象
#2
Well i can give you an example why to use something like that. Think of a game where you want to store your level and enemies in an XML file. When you parse this file, you might have an element like this.
那么我可以给你一个例子,为什么要使用这样的东西。想象一下你想要将你的等级和敌人存储在XML文件中的游戏。解析此文件时,您可能有这样的元素。
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
what you can do now is, create dynamically the objects found in your level file.
你现在可以做的是,动态创建你的关卡文件中找到的对象。
foreach(XmlNode node in doc) var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
This is very useful, for building dynamic enviroments. Of course its also possible to use this for Plugin or addin scenarios and alot more.
这对于构建动态环境非常有用。当然它也可以用于插件或插件场景等等。
#3
My good friend MSDN can explain it to you, with an example
我的好朋友MSDN可以通过一个例子向您解释
Here is the code in case the link or content changes in the future:
以下是链接或内容在未来发生变化时的代码:
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
#4
You can also do this -
你也可以这样做 -
var handle = Activator.CreateInstance("AssemblyName", "Full name of the class including the namespace and class name");var obj = handle.Unwrap();
#5
A good example could be next: for instance you have a set of Loggers and you allows user to specify type to be used in runtime via configuration file.
下一个好例子就是:例如,你有一组记录器,你允许用户通过配置文件指定在运行时使用的类型。
Then:
string rawLoggerType = configurationService.GetLoggerType();Type loggerType = Type.GetType(rawLoggerType);ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
OR another case is when you have a common entities factory, which creates entity, and is also responsible on initialization of an entity by data received from DB:
或者另一种情况是当你有一个公共实体工厂,它创建实体,并且还负责通过从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;}
#6
The Activator.CreateInstance
method creates an instance of a specified type using the constructor that best matches the specified parameters.
Activator.CreateInstance方法使用与指定参数最匹配的构造函数创建指定类型的实例。
For example, let's say that you have the type name as a string, and you want to use the string to create an instance of that type. You could use Activator.CreateInstance
for this:
例如,假设您将类型名称作为字符串,并且您希望使用该字符串来创建该类型的实例。您可以使用Activator.CreateInstance:
string objTypeName = "Foo";Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
Here's an MSDN article that explains it's application in more detail:
这是一篇MSDN文章,更详细地解释了它的应用程序:
#7
Building off of deepee1 and this, here's how to accept a class name in a string, and then use it to read and write to a database with LINQ. I use "dynamic" instead of deepee1's casting because it allows me to assign properties, which allows us to dynamically select and operate on any table we want.
构建deepee1和this,这里是如何接受字符串中的类名,然后使用它来读取和写入LINQ数据库。我使用“dynamic”而不是deepee1的转换,因为它允许我分配属性,这允许我们动态地选择和操作我们想要的任何表。
Type tableType = Assembly.GetExecutingAssembly().GetType("NameSpace.TableName");ITable itable = dbcontext.GetTable(tableType);//prints contents of the tableforeach (object y in itable) { string value = (string)y.GetType().GetProperty("ColumnName").GetValue(y, null); Console.WriteLine(value);}//inserting into a tabledynamic tableClass = Activator.CreateInstance(tableType);//Alternative to using tableType, using Tony's tipsdynamic tableClass = Activator.CreateInstance(null, "NameSpace.TableName").Unwrap();tableClass.Word = userParameter;itable.InsertOnSubmit(tableClass);dbcontext.SubmitChanges();//sql equivalentdbcontext.ExecuteCommand("INSERT INTO [TableNme]([ColumnName]) VALUES ({0})", userParameter);
#8
Why would you use it if you already knew the class and were going to cast it?Why not just do it the old fashioned way and make the class like you always make it? There's no advantage to this over the way it's done normally.Is there a way to take the text and operate on it thusly:
如果你已经知道了这个课程并且要去施展它,你为什么要使用它呢?为什么不按照老式的方式去做,让你的课程像往常一样?这通过正常的方式没有任何优势。有一种方法可以获取文本并对其进行操作:
label1.txt = "Pizza" Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);p.method1();p.method2();
If I already know its a Pizza there's no advantage to:
如果我已经知道它的披萨,那就没有优势:
p = (Pizza)somefancyjunk("Pizza"); overPizza p = new Pizza();
but I see a huge advantage to the Magic method if it exists.
但是如果它存在的话,我认为Magic方法有很大的优势。
#9
Coupled with reflection, I found Activator.CreateInstance to be very helpful in mapping stored procedure result to a custom class as described in the following answer.
结合反射,我发现Activator.CreateInstance在将存储过程结果映射到自定义类时非常有用,如下面的答案所述。
#1
Say you have a class called MyFancyObject
like this one below:
假设您有一个名为MyFancyObject的类,如下所示:
class MyFancyObject{ public int A { get;set;}}
It lets you turn:
它可以让你转:
String ClassName = "MyFancyObject";
Into
MyFancyObject obj;
Using
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
and can then do stuff like:
然后可以做类似的事情:
obj.A = 100;
That's its purpose. It also has many other overloads such as providing a Type
instead of the class name in a string. Why you would have a problem like that is a different story. Here's some people who needed it:
这是它的目的。它还有许多其他重载,例如在字符串中提供Type而不是类名。为什么你会有这样的问题是一个不同的故事。以下是一些需要它的人:
- Createinstance() - Am I doing this right?
- C# Using Activator.CreateInstance
- Creating an object without knowing the class name at design time
Createinstance() - 我这样做了吗?
C#使用Activator.CreateInstance
在设计时不知道类名创建对象
#2
Well i can give you an example why to use something like that. Think of a game where you want to store your level and enemies in an XML file. When you parse this file, you might have an element like this.
那么我可以给你一个例子,为什么要使用这样的东西。想象一下你想要将你的等级和敌人存储在XML文件中的游戏。解析此文件时,您可能有这样的元素。
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
what you can do now is, create dynamically the objects found in your level file.
你现在可以做的是,动态创建你的关卡文件中找到的对象。
foreach(XmlNode node in doc) var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
This is very useful, for building dynamic enviroments. Of course its also possible to use this for Plugin or addin scenarios and alot more.
这对于构建动态环境非常有用。当然它也可以用于插件或插件场景等等。
#3
My good friend MSDN can explain it to you, with an example
我的好朋友MSDN可以通过一个例子向您解释
Here is the code in case the link or content changes in the future:
以下是链接或内容在未来发生变化时的代码:
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
#4
You can also do this -
你也可以这样做 -
var handle = Activator.CreateInstance("AssemblyName", "Full name of the class including the namespace and class name");var obj = handle.Unwrap();
#5
A good example could be next: for instance you have a set of Loggers and you allows user to specify type to be used in runtime via configuration file.
下一个好例子就是:例如,你有一组记录器,你允许用户通过配置文件指定在运行时使用的类型。
Then:
string rawLoggerType = configurationService.GetLoggerType();Type loggerType = Type.GetType(rawLoggerType);ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
OR another case is when you have a common entities factory, which creates entity, and is also responsible on initialization of an entity by data received from DB:
或者另一种情况是当你有一个公共实体工厂,它创建实体,并且还负责通过从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;}
#6
The Activator.CreateInstance
method creates an instance of a specified type using the constructor that best matches the specified parameters.
Activator.CreateInstance方法使用与指定参数最匹配的构造函数创建指定类型的实例。
For example, let's say that you have the type name as a string, and you want to use the string to create an instance of that type. You could use Activator.CreateInstance
for this:
例如,假设您将类型名称作为字符串,并且您希望使用该字符串来创建该类型的实例。您可以使用Activator.CreateInstance:
string objTypeName = "Foo";Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
Here's an MSDN article that explains it's application in more detail:
这是一篇MSDN文章,更详细地解释了它的应用程序:
#7
Building off of deepee1 and this, here's how to accept a class name in a string, and then use it to read and write to a database with LINQ. I use "dynamic" instead of deepee1's casting because it allows me to assign properties, which allows us to dynamically select and operate on any table we want.
构建deepee1和this,这里是如何接受字符串中的类名,然后使用它来读取和写入LINQ数据库。我使用“dynamic”而不是deepee1的转换,因为它允许我分配属性,这允许我们动态地选择和操作我们想要的任何表。
Type tableType = Assembly.GetExecutingAssembly().GetType("NameSpace.TableName");ITable itable = dbcontext.GetTable(tableType);//prints contents of the tableforeach (object y in itable) { string value = (string)y.GetType().GetProperty("ColumnName").GetValue(y, null); Console.WriteLine(value);}//inserting into a tabledynamic tableClass = Activator.CreateInstance(tableType);//Alternative to using tableType, using Tony's tipsdynamic tableClass = Activator.CreateInstance(null, "NameSpace.TableName").Unwrap();tableClass.Word = userParameter;itable.InsertOnSubmit(tableClass);dbcontext.SubmitChanges();//sql equivalentdbcontext.ExecuteCommand("INSERT INTO [TableNme]([ColumnName]) VALUES ({0})", userParameter);
#8
Why would you use it if you already knew the class and were going to cast it?Why not just do it the old fashioned way and make the class like you always make it? There's no advantage to this over the way it's done normally.Is there a way to take the text and operate on it thusly:
如果你已经知道了这个课程并且要去施展它,你为什么要使用它呢?为什么不按照老式的方式去做,让你的课程像往常一样?这通过正常的方式没有任何优势。有一种方法可以获取文本并对其进行操作:
label1.txt = "Pizza" Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);p.method1();p.method2();
If I already know its a Pizza there's no advantage to:
如果我已经知道它的披萨,那就没有优势:
p = (Pizza)somefancyjunk("Pizza"); overPizza p = new Pizza();
but I see a huge advantage to the Magic method if it exists.
但是如果它存在的话,我认为Magic方法有很大的优势。
#9
Coupled with reflection, I found Activator.CreateInstance to be very helpful in mapping stored procedure result to a custom class as described in the following answer.
结合反射,我发现Activator.CreateInstance在将存储过程结果映射到自定义类时非常有用,如下面的答案所述。