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('测试反射机制')"});//调用方法
反射机制对应设计模式中的策略模式。
相关文章推荐
- 判断两个字符串中出现的字符是否完全一样(顺序可以不同)
- 函数: 判断两个字符串是否完全一样
- java 判断两个对象是否为同一个对象实例代码
- java判断两个文件的内容是否完全一样
- C#中安全的判断两个实例是否不等(不是同一个)
- 判断一个数组(有n个数据,数组的值大于等于1小于等于N)里面是否有两个一样的数据
- 判断两个数组是否完全一样(未完成)
- Python判断两个list是否是父子集关系的实例
- 判断一个字符串是否是有其他两个字符串交错构成的(Interleaving String)
- [置顶] 如何判断两个IP大小关系及是否在同一个网段中
- 判断一个数是否是完全数
- 判断输入的一个数是否为回文数c++代码实例及运行结果
- shell脚本使用两个数组,判断一个变量是否在数组里面的例子
- 判断一个类或实例是否继承自某类的python代码
- 子网掩码判断两个IP地址是否在一个子网中
- 紫书章七例五 Krypton Factor UVA - 129(dfs)判断一个字符串中是否包含两个相邻子串
- C# WINFORM判断程序是否运行,且只能运行一个实例
- 简单编程(十四)定义一个方法能够判断并返回两个整数的最大值,并调用自己的方法测试是否正确。
- WithinPastYears、WithinPastMonths、WithinPastWeeks、WithinPastDays ... 判断两个时间差是否在一个指定范围内
- python 判断一个类或实例是否继承自某类