有人可以解释 Activator.CreateInstance()
详细目的吗?
c#.net
这样做的方法Object xyz = Class.forName(className).newInstance();
。
有人可以解释 Activator.CreateInstance()
详细目的吗?
c#.net
这样做的方法Object xyz = Class.forName(className).newInstance();
。
Answers:
假设您在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
。
接下来是一个很好的例子:例如,您有一组Logger,并且允许用户通过配置文件指定要在运行时使用的类型。
然后:
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
是,如果您不知道要在设计时实例化的对象类型。在此示例中,Foo
由于将其强制转换为type ,因此您清楚地知道了它的类型Foo
。您永远不会这样做,因为您可以做到Foo foo = new Foo()
。
建立在deepee1和this的基础上,这是如何在字符串中接受类名,然后使用它通过LINQ读写数据库。我使用“ dynamic”而不是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();
但我认为Magic方法(如果存在)具有巨大优势。
CreateInstance(Type type)
与CreateInstance<T>()
重载匹配。