C#反射机制
最近仔细学习了一下C#的反射机制,希望能和大家分享。 提到反射我想大家都不陌生,反射提供了封装程序集、模块和类型的对象( Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性,所在命名空间using System.Reflection。
反射的作用:
- 1.使用反射可以动态创建类型的实例,然后将实例再邦定到现有的对象或从现有对象中获取类型。
- 2.应用程序需要在运行时从某个特定的程序集中载入特定的类型,以创建特定类型的实例。
正是因为反射的特性(动态创建实例)所以在多个模块之间减少代码的紧偶合方面,利用反射可以起到了很大的改善。但是反射也有它的弊端,就是要以牺牲性能为代价,而且有些信息利用反射是无法得到的。在使用时要根据情况进行选择。我想通过下图的层次模型大家可能会更明白它的机制。
![](https://pic002.cnblogs.com/img/deymmtd/200909/2009092511240442.gif)
以上关于反射知识了解之后,在通过代码大家可能会更好的理解反射:
首先在Vs2008中创建一个类型,命名为ReflectDemo类库。并添加一个名为ReflectTest的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SKY.ReflectDemo
{
public class ReflectTest : IPerson
{
private string _name;
private int _age;
public string Name { get { return this._name; } set { this._name = value; } }
public int Age { get { return this._age; } set { this._age = value; } }
public ReflectTest(string name, int age)
{
this._name = name;
this._age = age;
}
public string WelcomeInfo(string name)
{
return "welcome come here " + name;
}
public static string WriteStaticInfo(string name)
{
return "welcome come here static" + name;
}
public static string WriteStaticNoParam()
{
return "Static and No parma";
}
public void Show(string info)
{
Console.WriteLine(info);
}
public ReflectTest() { }
public string WriteNoPara()
{
return "你使用的是无参的方法";
}
private string WritePrivate()
{
return "私有类型的方法";
}
#region IPerson 成员
public int Add()
{
return Age;
}
#endregion
}
public interface IPerson
{
/// <summary>
/// 添加对象
/// </summary>
/// <returns></returns>
int Add();
}
}
然后再创建一个客户端程序:例如clientTestDemo,添加刚刚新建的程序集引用,引用命名空间using System.Reflection
class Program
{
delegate string TestDelegate(string name);
static void Main(string[] args)
{
//*********************引导程序集************************//
//Assembly ass = Assembly.LoadFrom(("SKY.ReflectDemo.dll"));
//Assembly ass=Assembly.GetAssembly(typeof(SKY.ReflectDemo.ReflectTest);
Assembly ass = Assembly.Load("SKY.ReflectDemo");//功能同上
Console.Write(ass.FullName+"\n");
//*********************显示该dll下所有的类***************//
foreach (Type type in ass.GetTypes())
{
Console.Write(type.Name+"\n");
}
//*********************显示该dll下指定类**************//
Type itype = ass.GetType("SKY.ReflectDemo.ReflectTest");
Console.Write(itype.Name);
Type itype1 = typeof(SKY.ReflectDemo.ReflectTest);
//********************所有模块***********************//
foreach (Module temp in ass.GetModules())
{
Console.WriteLine(temp.Assembly.FullName);
}
//********************创建该类的实例,后面的param为有参构造函数的参数******************//
object[] param = { "test", 30 };//构造函数参数
SKY.ReflectDemo.ReflectTest temp1 = (SKY.ReflectDemo.ReflectTest)Activator.CreateInstance(itype1, param);
// SKY.ReflectDemo.ReflectTest temp1 = (SKY.ReflectDemo.ReflectTest)ass.CreateInstance("SKY.ReflectDemo.ReflectTest");
Console.WriteLine(temp1.WriteNoPara());
//******************************显示所有的共有方法************************************//
MethodInfo[] methods = itype.GetMethods();
Console.WriteLine("------------------------显示所有的共有方法-------------------------");
foreach (MethodInfo temp in methods)
{
Console.WriteLine(temp.Name);
}
//******************************显示特定方法************************************//
Console.WriteLine("------------------------显示特定方法------------------------------");
MethodInfo method1 = itype.GetMethod("WriteStaticInfo"); //带参的静态方法
Console.WriteLine(method1.Name);
object[] param1 = { "使用的是静态方法" };
string s1 = (string)method1.Invoke(null, param1);
Console.WriteLine("执行后:"+s1+"\n");
MethodInfo method2 = itype.GetMethod("WriteStaticNoParam");//无参静态方法
Console.WriteLine(method2.Name);
string s2 = method2.Invoke(null, null) as string;
Console.WriteLine("执行后:" + s2 + "\n");
MethodInfo method3 = itype.GetMethod("WelcomeInfo");//带参的非静态方法
Console.WriteLine(method3.Name);
object[] param2 = { "使用的是带有参数的非静态方法" };
string s3 = (string)method3.Invoke(temp1, param2);
Console.WriteLine("执行后:" + s3 + "\n");
MethodInfo method4 = itype.GetMethod("WriteNoPara");//无参非静态方法
Console.WriteLine(method4.Name);
string s4 = method4.Invoke(temp1, null) as string;
Console.WriteLine("执行后:" + s4 + "\n");
MethodInfo method5 = itype.GetMethod("WritePrivate", BindingFlags.NonPublic | BindingFlags.Instance);//无参私有非静态方法
Console.WriteLine(method5.Name);
string s5 = method5.Invoke(temp1, null) as string;
Console.WriteLine("执行后:" + s5 + "\n");
MethodInfo method6 = itype.GetMethod("Show");//返回类型为void的方法
Console.WriteLine(method6.Name);
object[]param3={"returnType is void"};
string s6 = method6.Invoke(temp1, param3) as string;
Console.WriteLine(s6);
//***********************************显示所有属性*********************************88//
Console.WriteLine("------------------------显示所有属性------------------------------");
PropertyInfo[] pros = itype.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (PropertyInfo temp in pros)
{
Console.WriteLine(temp.Name);
}
//***********************************显示特定属性*********************************88//
Console.WriteLine("------------------------显示特定属性------------------------------");
PropertyInfo proName = itype.GetProperty("Name");
proName.SetValue(temp1, "testName",null);
Console.WriteLine(proName.GetValue(temp1, null));
//***********************************显示构造函数*********************************88//
Console.WriteLine("------------------------显示构造函数------------------------------");
ConstructorInfo[] cons = itype.GetConstructors();
foreach (ConstructorInfo t in cons)
{
Console.WriteLine(t.ToString());
}
//***********************************显示特定构造函数形式*********************************88//
Console.WriteLine("------------------------显示特定构造函数形式------------------------------");
ConstructorInfo con1= itype.GetConstructor(new Type[] { typeof(string), typeof(int) });
Console.WriteLine(con1);
ConstructorInfo con2 = itype.GetConstructor(new Type[] { });
Console.WriteLine(con2);
//**************************************委托的使用*********************************************//
Console.WriteLine("------------------------委托的使用------------------------------");
TestDelegate td = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), temp1, "WelcomeInfo");//非静态方法
Console.WriteLine(td("使用的是带有参数的非静态方法"));
TestDelegate td2 = Delegate.CreateDelegate(typeof(TestDelegate), method1) as TestDelegate;//静态方法
Console.WriteLine(td2("使用静态方法"));
// TestDelegate td1 = new TestDelegate(SKY.ReflectDemo.ReflectTest.WriteStaticInfo);
// Console.WriteLine(td1("使用的是带有参数的非静态方法222")); 同上
运行结果如下:
有什么不对,请大家批评指确。