一、反射的使用
可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然後,可以調用類型的方法或訪問其字段和屬性。
需要使用的命名空間:System.Reflection
反射的作用很多,下面的例子主要是看一下怎麼動態的調用類中的方法。
例子類
{
private string _prop1;
public string Prop1
{
get { return _prop1; }
set { _prop1 = value; }
}
public void Write1(string strText)
{
Console.WriteLine("111111111:" + strText);
}
public void Write2(string strText)
{
Console.WriteLine("222222222:" + strText);
}
public void MyWrite(string strText)
{
Console.WriteLine("3333333333:" + strText);
}
}
這個例子中提供了三個方法和一個屬性,下面的代碼來動態的調用它們:
BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
Type t = typeof(ReflTest1);
MethodInfo[] mi = t.GetMethods(flags);
Object obj = Activator.CreateInstance(t);
foreach (MethodInfo m in mi)
{
if (m.Name.StartsWith("Write"))
{
m.Invoke(obj, new object[] { strText });
} [Page]
}
MethodInfo mMy = t.GetMethod("MyWrite");
if (mMy != null)
{
mMy.Invoke(obj, new object[] { strText });
}
BindingFlags用來設置要取得哪些類型的方法,然後我們就可以取得這些方法來動態的調用。(當然爲了可以循環的調用方法,在方法的命名方面可以自己指定一個規則)
二、動態生成類
我們可以在程序運行過程中調用.NET中提供的編譯類,動態的將一段string編譯成一個類,然後再通過反射來調用它
需要使用的命名空間:System.CodeDom System.CodeDom.Compiler Microsoft.CSharp System.Reflection
動態創建、編譯類的代碼如下:
{
//創建編譯器實例。
provider = new CSharpCodeProvider();
//設置編譯參數。
paras = new CompilerParameters();
paras.GenerateExecutable = false;
paras.GenerateInMemory = true;
//創建動態代碼。
StringBuilder classSource = new StringBuilder();
classSource.Append("public class DynamicClass /n");
classSource.Append("{/n");
//創建屬性。
classSource.Append(propertyString("aaa"));
classSource.Append(propertyString("bbb"));
classSource.Append(propertyString("ccc"));
classSource.Append("}");
System.Diagnostics.Debug.WriteLine(classSource.ToString());
//編譯代碼。
CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource.ToString());
//獲取編譯後的程序集。
Assembly assembly = result.CompiledAssembly; [Page]
return assembly;
}
private static string propertyString(string propertyName)
{
StringBuilder sbProperty = new StringBuilder();
sbProperty.Append(" private int _" + propertyName + " = 0;/n");
sbProperty.Append(" public int " + "" + propertyName + "/n");
sbProperty.Append(" {/n");
sbProperty.Append(" get{ return _" + propertyName + ";} /n");
sbProperty.Append(" set{ _" + propertyName + " = value; }/n");
sbProperty.Append(" }");
return sbProperty.ToString();
}
propertyString方法就是用來拼寫字符串的
整個代碼比較簡單,主要步驟就是:1、拼寫類的字符串 2、調用CSharpCodeProvider類進行編譯得到程序集(assembly)
接下來就可以利用之前反射的方法來動態調用這個類中的屬性了:
object Class1 = assembly.CreateInstance("DynamicClass");
ReflectionSetProperty(Class1, "aaa", 10);
ReflectionGetProperty(Class1, "aaa");
object Class2 = assembly.CreateInstance("DynamicClass");
ReflectionSetProperty(Class1, "bbb", 20);
ReflectionGetProperty(Class1, "bbb");
DynamicClass是我動態類的類名,aaa和bbb是其中的屬性
ReflectionSetProperty和ReflectionGetProperty代碼如下:
給屬性賦值
{
PropertyInfo[] infos = objClass.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
if (info.Name == propertyName && info.CanWrite) [Page]
{
info.SetValue(objClass, value, null);
}
}
}
取得屬性的值
{
PropertyInfo[] infos = objClass.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
if (info.Name == propertyName && info.CanRead)
{
System.Console.WriteLine(info.GetValue(objClass, null));
}
}
}