运行时动态对象创建(我也不知道该叫什么名字,就姑且这么随便称呼了)确实很势大,应该是很有威力的。程序员,贴代码最直接了:
int n = System.Activator.CreateInstance<int>();
这一句没啥可说的,根据类别创建对象。这里要注意的是int型别是编译时可确定的。不是typeof(int)类型。
Type type = Type.GetType("System.Int32", false, true);
object o = System.Activator.CreateInstance(type);
Debug.Assert(o.GetType() == typeof(int));
第一句是根据类型名称得到类型Type。对于工厂模式有印象的同学肯定知道该特性是多么有用。注意这里类型名称不能用int,而必须是类型的全写,int之类是C#编译器的关键字,而不是CLR的。
第二句是根据Type生成对象。这对于有运行时动态生成对象需求的系统非常有用。不过这里的object o声明不能高级到哪去,至多你后面加一个as IYourInterface,不过还是无法在编译代码里直接描述对象类别。
Type type = typeof(int);
Type listType = typeof(List<>);
Type[] typeArgs = { type };
Type genericType = listType.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(genericType);
Debug.Assert(o.GetType() == typeof(List<int>));
这段代码更奇特了,可以动态的生成泛型对象。如果你只有在运行时才知道泛型容器的类型参数,问题该如何描述呢?上面的解决方案非常直爽,要的就是这感觉。
C#动态方法调用
/// <summary>
/// 该类将被独立编入Class1.dll汇编
/// </summary>
class Class1
{
public static string method1()
{
return "I am Static method (method1) in class1";
}
public string method2()
{
return "I am a Instance Method (method2) in Class1";
}
public string method3(string s)
{
return "Hello " + s;
}
}
/// <summary>
/// 该类独立放入Test.exe汇编
/// </summary>
class DynamicInvoke
{
public static void Main(string[] args)
{
// 动态加载汇编
string path = "Class1.dll";
Assembly assembly = Assembly.Load(path);
// 根据类型名得到Type
Type type = assembly.GetType("Class1");
// 根据方法名动态调用静态方法
string str = (string)type.InvokeMember("method1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { });
Console.WriteLine(str);
// 根据类型动态创建对象
object o = Activator.CreateInstance(type);
// 根据方法名动态调用动态对象的成员方法
str = (string)type.InvokeMember("method2", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { });
Console.WriteLine(str);
// 根据方法名动态调用动态对象的有参成员方法
object[] par = new object[] { "kunal" };
str = (string)type.InvokeMember("method3", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, par);
Console.WriteLine(str);
// 带out修饰的InvokeMember
// System.Int32 中 public static bool TryParse(string s, out int result) 方法的调用
var arguments = new object[] { str, null}; // 注意这里只能将参数写在外面,out参数为null也没有关系
typeof(int).InvokeMember("TryParse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static,
null, null, arguments);
Console.WriteLine(arguments[1]);
}
}
(原文地址:http://blog.sina.com.cn/dekun1002 )s