Activator.CreateInstance的用途举例?

有人可以详细解释Activator.CreateInstance()目的吗?

假设你有一个名为MyFancyObject类,如下所示:

 class MyFancyObject { public int A { get;set;} } 

它可以让你转向:

 String ClassName = "MyFancyObject"; 

 MyFancyObject obj; 

运用

 obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName)) 

然后可以做这样的东西:

 obj.A = 100; 

这是它的目的。 它也有许多其他的重载,比如在一个string中提供一个Type而不是类名。 为什么你会有这样的问题是一个不同的故事。 以下是一些需要它的人:

  • Createinstance() – 我是这样做的吗?
  • C#使用Activator.CreateInstance
  • 在devise时不知道类名创build一个对象

那么我可以给你一个例子,为什么要使用类似的东西。 想想一个游戏,你想在XML文件中存储你的关卡和敌人。 当你parsing这个文件时,你可能有这样一个元素。

 <Enemy X="10" Y="100" Type="MyGame.OrcGuard"/> 

你现在可以做的是dynamic创build你的关卡文件中find的对象。

 foreach(XmlNode node in doc) var enemy = Activator.CreateInstance(null, node.Attributes["Type"]); 

这对构builddynamic环境非常有用。 当然它也可以使用这个插件或插件的情况下,还有更多。

我的好朋友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(); 

接下来是一个很好的例子:例如,你有一组logging器,并允许用户通过configuration文件指定在运行时使用的types。

然后:

 string rawLoggerType = configurationService.GetLoggerType(); Type loggerType = Type.GetType(rawLoggerType); ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger; 

或者另一种情况是当你有一个共同的实体工厂,它创build了实体,并且还负责通过从数据库接收到的数据对实体进行初始化:

(伪代码)

 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; } 

Activator.CreateInstance方法使用最符合指定参数的构造函数创build指定types的实例。

例如,假设您的types名称是一个string,并且您希望使用该string来创build该types的实例。 你可以使用Activator.CreateInstance来达到这个目的:

 string objTypeName = "Foo"; Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName)); 

这是一个MSDN文章,更详细地解释它的应用程序:

http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

基于deepee1和这个 ,下面是如何接受一个string中的类名,然后用它来读写LINQ的数据库。 我使用“dynamic”而不是deepee1的投射,因为它允许我分配属性,这允许我们dynamicselect和操作任何我们想要的表。

 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); 

如果你已经认识了这个class,那么你为什么要使用它呢? 为什么不按照老式的方式去做,让class级像你一样做呢? 在正常情况下,没有任何优势。 有没有办法采取文本,并在其上运作:

 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(); 

但是如果存在的话,我看到魔法的巨大优势。