public static bool ObjectEquel(TempClass obj1, TempClass obj2)
{
Type type1 = obj1.GetType();
Type type2 = obj2.GetType();
System.Reflection.PropertyInfo[] properties1 = type1.GetProperties();
System.Reflection.PropertyInfo[] properties2 = type2.GetProperties();
bool IsMatch = true;
for (int i = 0; i < properties1.Length; i++)
{
string s = properties1[i].DeclaringType.Name;
if (properties1[i].GetValue(obj1, null).ToString() != properties2[i].GetValue(obj2, null).ToString())
{
IsMatch = false;
break;
}
}
return IsMatch;
}
1.什么是反射
Reflection,中文翻译为 反射。
这是.Net中获取 运行时类型信息的方式,. 当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。Net的应用程序由几个部分:'程序集(Assembly)’、'模块(Module)’、'类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,
System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码
System.Reflection.Assembly
System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type
以下是上面几个类的使用方法:
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
上面列出的这些classes(除ParameterInfo外)的访问操作,要通过一个Type对象来完成。比如我们要获得一个装配件的“成员函数”就要这样做:
System.Reflection.Assembly ass=System.Reflection.Assembly.LoadFrom(fileName);
Type[] tp=ass.GetTypes();
System.Reflection.MethodInfo[] mi=tp[0].GetMethods();
使用同样的方法我们还可以得到其它的信息,如下:
获得“构造函数”信息:System.Reflection.ConstructorInfo[] ci=tp[0].GetConstructors();
获得“属性”信息:System.Reflection.PropertyInfo[] pi=tp[0].GetProperties();
获得“数据成员”信息:System.Reflection.FieldInfo[] fi=tp[0].GetFields();
获得“事件”信息:System.Reflection.EventInfo[] ei=tp[0].GetEvents();
此外,我们可以通过ParameterInfo类来获取“成员函数”和“构造函数”的参数信息,如下:
获取“成员函数”的参数信息:System.Reflection.ParameterInfo[] pi=mi[0].GetParameters();
获取“构造函数”的参数信息:System.Reflection.ParameterInfo[] pi=ci[0].GetParameters();
ParameterInfo类有两个重要的属性:Name和ParameterType。通过它们我们可以得到“参数”的名称和数据类型。
反射的作用:
1、可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型
2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
3、反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。
实现步骤:
1,导入using System.Reflection;
2,Assembly.Load("程序集")加载程序集,返回类型是一个Assembly
3, foreach (Type type in assembly.GetTypes())
{
string t = type.Name;
}
得到程序集中所有类的名称
4,Type type = assembly.GetType("程序集.类名");获取当前类的类型
5,Activator.CreateInstance(type); 创建此类型实例
6,MethodInfo mInfo = type.GetMethod("方法名");获取当前方法
7,mInfo.Invoke(null,方法参数);
例子1.
public static void fun(ClassA g) { Type type1 = g.GetType(); System.Reflection.PropertyInfo[] properties1 = type1.GetProperties(); for (int i = 0; i < properties1.Length; i++) { if (properties1[i].PropertyType.Equals(typeof(Int32))) { properties1[i].SetValue(g, 32, null); Console.WriteLine(properties1[i].GetValue(g, null)); } } }
例子2
class Program { static void Main(string[] args) { classA a=new classA(); TestObjectType test =new TestObjectType(); Test.FucType(a); } } class classA { internal int iNumberA = 100; public int iNumberB = 200; private int property; public int Property { get { return property; } set { property = value; } } public void FunA() { Console.WriteLine("classA is a Fuction! "); } } class classB { } class TestObjectType { internal void FucType(object A) { Type objType = A.GetType(); Assembly objassembly = objType.Assembly; Type[] types = objassembly.GetTypes(); foreach (Type type in types) { Console.WriteLine("类名 " + type.FullName); // 获取类型的结构信息 ConstructorInfo[] myConstructor = type.GetConstructors(); Show(myConstructor); // 获取类型的字段信息 FieldInfo[] myField = type.GetFields(); Show(myField); // 获取方法的方法 MethodInfo[] myMethod = type.GetMethods(); Show(myMethod); // 获取属性的方法 PropertyInfo[] myProperty = type.GetProperties(); Show(myProperty); // 获取事件信息,这个Demo没有事件,所以就不写了 EventInfo } Console.ReadLine(); } // 显示数组的基本信息 private void Show(object[] myObject) { foreach (object var in myObject) { Console.WriteLine(var.ToString()); } Console.WriteLine("-------------------"); } }
例子3:
获得整个解决方案的所有Assembly 如果你不太清楚自己的解决方案中都用到了哪些Assembly,可以使用下面的方法,如果再想得到Assembly里的信息,请参见 4 namespace TestReflection { class Program { static void Main(string[] args) { // 遍历显示每个Assembly的名字 foreach (object var in Ax) { Console.WriteLine("Assembly的名字是: " + var.ToString()); // 使用一个已知的Assembly的名称,来创建一个Assembly // 通过CodeBase属性显示最初指定的程序集的位置 Console.WriteLine("最初指定的程序集TestReflection的位置: " + Assembly.Load("TestReflection").CodeBase); Console.ReadLine(); } } } }
例子4
源DLL类: using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Web.UI; using System.Collections; namespace cn.SwordYang { public class TextClass:System.Web.UI.Page { public static void RunJs(Page _page, string Source) { _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type="text/javascript">" + Source + ";</script>"); } } } //调用代码 System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型 object o = System.Activator.CreateInstance(t);//创建实例 System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法 mi.Invoke(o, new object[] { this.Page,"alert('测试反射机制')"});//调用方法 反射机制对应设计模式中的策略模式。