反射其实说白了就是,当你知道类的名字和位置。你可以在程序运行时直接创建实例调用它。没什么大不了的。
public class TestRef
{
string testStr = "";
public TestRef(string testStr)
{
this.testStr = testStr;
}
public void Print()
{
Console.WriteLine(testStr);
}
}
1、这里有一个测试类,有它的构造函数和一个测试的函数。我们现在通过反射来获取它的实例。
Type t = Type.GetType("反射.TestRef");//“反射”是命名空间
object[] o = new object[] { "hello" };
TestRef tr = (TestRef)Activator.CreateInstance(t, o);
tr.Print();
2、如果只需要获取一个函数,我们也能这么做。
MethodInfo met = t.GetMethod("Print");
met.Invoke(tr,null);
3、如果你需要创建一个DLL文件中的实例。你可以这么做
var instence = Assembly.Load("XXX.dll").CreateInstance("xxxxxx");
4、通过一个string的名字找到它的值。
class Program
{
public static string doc1 = "hello world";//获取的对象必须是要客观存在的。
// ....................省略号
string docname = "doc1";
//通过反射获取该对象,必须为public
FieldInfo myRef = typeof(Program).GetField(docname);
string doc = (string)myRef.GetValue(null);
}
5、好了。下面来玩一个高端的。动态编译一个String 中的代码。
string code = @"
using System;
namespace MyNamespace
{
public class MyClass
{
private string name;
public MyClass(string name)
{
this.name = name;
}
public void Test()
{
Console.WriteLine(""{0} - {1}"", name, DateTime.Now);
}
}
}
";
// 创建编译器对象
CSharpCodeProvider complier = new CSharpCodeProvider();
// 设置编译参数
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.dll");
options.GenerateInMemory = true;
options.OutputAssembly = "MyTest";
// 开始编译
CodeSnippetCompileUnit cu = new CodeSnippetCompileUnit(code);
CompilerResults cr = complier.CompileAssemblyFromDom(options, cu);
// 执行动态程序集相关内容。当然还是反射。
Type t2 = cr.CompiledAssembly.GetType("MyNamespace.MyClass");
object o2 = cr.CompiledAssembly.CreateInstance("MyNamespace.MyClass", false, BindingFlags.Default,
null, new object[] { "Tom" }, CultureInfo.CurrentCulture, null);
t2.InvokeMember("Test", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
null, o2, null);