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


    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('测试反射机制')"});//调用方法

反射机制对应设计模式中的策略模式。

 

 

posted @ 2013-08-14 11:04  zzlp  阅读(2456)  评论(0编辑  收藏  举报