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文章,更详细地解释它的应用程序:
基于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();
但是如果存在的话,我看到魔法的巨大优势。