您的位置:首页 > 编程语言 > C#

c#反射机制判断同一个类的两个实例的值是否完全一样

2013-08-14 11:04 302 查看


publicstaticboolObjectEquel(TempClassobj1,TempClassobj2)
{
Typetype1=obj1.GetType();
Typetype2=obj2.GetType();

System.Reflection.PropertyInfo[]properties1=type1.GetProperties();
System.Reflection.PropertyInfo[]properties2=type2.GetProperties();

boolIsMatch=true;
for(inti=0;i<properties1.Length;i++)
{
strings=properties1[i].DeclaringType.Name;
if(properties1[i].GetValue(obj1,null).ToString()!=properties2[i].GetValue(obj2,null).ToString())
{
IsMatch=false;
break;
}
}

returnIsMatch;
}




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.Assemblyass=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,导入usingSystem.Reflection;
2,Assembly.Load("程序集")加载程序集,返回类型是一个Assembly
3,foreach(Typetypeinassembly.GetTypes())
{
stringt=type.Name;
}
得到程序集中所有类的名称
4,Typetype=assembly.GetType("程序集.类名");获取当前类的类型
5,Activator.CreateInstance(type);创建此类型实例
6,MethodInfomInfo=type.GetMethod("方法名");获取当前方法
7,mInfo.Invoke(null,方法参数);

例子1.

publicstaticvoidfun(ClassAg)

{

Typetype1=g.GetType();

System.Reflection.PropertyInfo[]properties1=type1.GetProperties();

for(inti=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

classProgram
{
staticvoidMain(string[]args)
{
classAa=newclassA();
TestObjectTypetest=newTestObjectType();
Test.FucType(a);
}
}
classclassA
{
internalintiNumberA=100;
publicintiNumberB=200;
privateintproperty;
publicintProperty
{
get
{
returnproperty;
}
set
{
property=value;
}
}
publicvoidFunA()
{
Console.WriteLine("classAisaFuction!");
}
}
classclassB
{
}
classTestObjectType
{
internalvoidFucType(objectA)
{
TypeobjType=A.GetType();
Assemblyobjassembly=objType.Assembly;
Type[]types=objassembly.GetTypes();
foreach(Typetypeintypes)
{
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();
}
//显示数组的基本信息
privatevoidShow(object[]myObject)
{
foreach(objectvarinmyObject)
{
Console.WriteLine(var.ToString());
}
Console.WriteLine("-------------------");
}
}


例子3:

获得整个解决方案的所有Assembly
如果你不太清楚自己的解决方案中都用到了哪些Assembly,可以使用下面的方法,如果再想得到Assembly里的信息,请参见4
namespaceTestReflection
{
classProgram
{
staticvoidMain(string[]args)
{
//遍历显示每个Assembly的名字
foreach(objectvarinAx)
{
Console.WriteLine("Assembly的名字是:"+var.ToString());

//使用一个已知的Assembly的名称,来创建一个Assembly
//通过CodeBase属性显示最初指定的程序集的位置
Console.WriteLine("最初指定的程序集TestReflection的位置:"+Assembly.Load("TestReflection").CodeBase);
Console.ReadLine();
}
}
}
}


例子4

源DLL类:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Text.RegularExpressions;
usingSystem.Web.UI;
usingSystem.Collections;

namespacecn.SwordYang
{

publicclassTextClass:System.Web.UI.Page
{

publicstaticvoidRunJs(Page_page,stringSource)
{
_page.ClientScript.RegisterStartupScript(_page.GetType(),"","<scripttype=\"text/javascript\">"+Source+";</script>");

}

}

}

//调用代码

System.Reflection.Assemblyass=Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll"));//加载DLL
System.Typet=ass.GetType("cn.SwordYang.TextClass");//获得类型
objecto=System.Activator.CreateInstance(t);//创建实例

System.Reflection.MethodInfomi=t.GetMethod("RunJs");//获得方法

mi.Invoke(o,newobject[]{this.Page,"alert('测试反射机制')"});//调用方法

反射机制对应设计模式中的策略模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐