zoukankan      html  css  js  c++  java
  • .Net Reflection反射技术

    这里写一下个人对.Net下反射技术的理解:

    第一部分:个人讲讲反射

    反射机制是一种运行时获取类(Type对象)和动态调用对象的成员的机制。

    a.可以获取有关已加载的程序集和在其中定义的类型(如类、接口和值类型)的成员信息;

    b.可以使用反射在运行时创建指定类的对象,以及调用和访问这些对象的成员。

    这种动态获取的信息以及动态调用对象的方法的功能称为反射机制。

    比如在myReflect.UI下定义了一个MyLyfeng类:

    public class MyLyfeng
        {
           //无参构造函数

           //有参数构造函数
           public MyLyfeng(string name)
           {
               this.name = name;
           }
           //私有字段
            private int beautyNum;

            public int BeautyNum
            {
                get { return beautyNum; }
                set { beautyNum = value; }
            }

            private string name;

            public string Name
            {
                get { return name; }
                set { name = value; }
            }


           //带返回值无参数公共方法
           public string SayName()
           {
               //逻辑
               return null;
           }
           //无参数无返回值私有方法
           private void Sleep()
           {
             //逻辑
           }
           //有参无返回值
           public void SayHello(string name)
           {
             //逻辑
           }
           //有参数有返回值
           public string ReturnParam(string param)
           {
               return param;
           }
        }

    1.一般情况想要得到MyLyfeng类的实例对象,那么只需要一句代码:

       //MyLyfeng lyf = new MyLyfeng() { BeautyNum=100};
         MyLyfeng lyf2 = new MyLyfeng("My");

    除了以上使用new的方法之外,还可以使用Reflection技术对MyLyfeng类进行操作.

    2.本地动态创建

               Type type=typeof(MyLyfeng);//本地可以访问到MyLyfeng类
                   //无参构造函数
                   object obj=Activator.CreateInstance(type);
                   //有参构造函数
                  ConstructorInfo c= type.GetConstructor(new Type[]{typeof(string) });//构造函数的实参类型
                  c.Invoke(new object[] { "name"});//实参
                //公共的

                       //字段操作
                       FieldInfo field= type.GetField("name");
                       field.GetValue(obj);//obj.field
                       field.SetValue(obj,"Lyfeng");
                        //属性操作
                       PropertyInfo  property =type.GetProperty("BeautyNum");
                       property.GetValue(obj, null);//obj.BeautyNum
                       property.SetValue(obj, 101,null);

                //私有的
                       //字段操作
                        FieldInfo[] fields =type.GetFields(BindingFlags.NonPublic);
                        foreach (FieldInfo item in fields)
                        {
                            
                        }
                         //属性操作
                        PropertyInfo[] propertys = type.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance);
                        foreach (PropertyInfo item in propertys)
                        {
                            
                        }
                //方法操作
                        //无参无返回值
                       MethodInfo method=type.GetMethod("Sleep");
                       method.Invoke(obj, null);
                        //有参无返回值
                       MethodInfo method1 = type.GetMethod("SayHello");
                       method1.Invoke(obj, new object[] { "name"});
                        //无参有返回值
                        MethodInfo method2=type.GetMethod("SayName");
                        object returnValue=method2.Invoke(obj,null);
                        //有参数又返回值
                        MethodInfo method3=type.GetMethod("ReturnParam");
                        object ReturnValue=method3.Invoke(obj,new object[]{"param"});
                //接口操作
                       //判断当前type是否实现IHarry接口
                        typeof(IHarry).IsAssignableFrom(type);

    以上是一些比较的常用用法的列举,但是,在实际开发中我们可能并不能直接访问到MyLyfeng,那么需要进行一小点的改动,代码如下:

    3.异地动态创建

    假设在另一个类库IFrancis中有一个Francis类,在myReflection.UI下不能访问到它,我们只需要将IFrancis.dll生成到(或者复制一份到myReflection.UI到bin下),

    然后使用反射得到实例对象:

    string path=AppDomain.CurrentDomain.BaseDirectory;
                  Assembly ass = Assembly.LoadFrom(path + "IFrancis.dll");
                  Type ftype= ass.GetType("IFrancis.Francis");
                  object fobj=Activator.CreateInstance(ftype);
                      //剩余同理

    第二部分:个人用用反射

    使用反射技术,动态拼接sql语句

    Insert示例1:

    int beautyNum = 102;
    string name = "name";

    System.Text.StringBuilder sb = new StringBuilder()

    Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IFrancis.dll");
    Type type = ass.GetType("IFrancis.Francis");
    string tableName = type.Name;

    sb.AppendFormat(" Insert into {0} (", tableName);
    PropertyInfo[] propertys = type.GetProperties();
    foreach (PropertyInfo item in propertys)
    {
        sb.Append(item.Name + ",");
    }
    //去掉逗号
    sb.Remove(sb.Length - 1, 1);
    sb.Append(") values(" + beautyNum + ",'" + name + "')");
    Note:这样的写法,是根据IFrancis.dll程序集的属性为准来生成sql语句,一般的话,我个人会使用另外一种,根据Model实体对象来作为依据:
    Insert示例2:

     MFrancis model = new MFrancis() { BeautyNum = 103, Name = "name" };
     string where = " where ....";

    System.Text.StringBuilder updatesb = new StringBuilder();

    Type type=Typeof(MFrancis);

    string tableName=type.Name;

    sb.AppendFormat(" insert into {0} (",tableName);
                PropertyInfo[]  PI= typeof(MFrancis).GetProperties();
                List<SqlParameter> list2 = new List<SqlParameter>();
                for (int i = 0; i < PI.Length; i++)
                {
                    sb.Append(PI[i].Name+",");
                }
                sb.Remove(sb.Length-1,1);
                sb.Append(") values(");
                for (int i = 0; i < PI.Length; i++)
                {
                    sb.Append("@"+PI[i].Name+",");
                    SqlParameter p = new SqlParameter("@"+PI[i].Name,PI[i].GetValue(model,null));
                    list2.Add(p);
                }
                sb.Remove(sb.Length-1,1);

    update示例:

     System.Text.StringBuilder updatesb = new StringBuilder();

    PropertyInfo[] pi = typeof(MFrancis).GetProperties();//Model
                
                List<SqlParameter> list = new List<SqlParameter>();
                updatesb.AppendFormat("update {0} set ", tableName);


                for (int i = 0; i < pi.Length; i++)
                {
                    updatesb.AppendFormat(pi[i].Name + "=@" + pi[i].Name + ",");
                    SqlParameter ps = new SqlParameter("@" + pi[i].Name, pi[i].GetValue(model, null));//类.属性名
                    list.Add(ps);
                }
                updatesb.Remove(updatesb.Length - 1, 1);
                if (string.IsNullOrEmpty(where))
                {
                    updatesb.Append(where);
                }
    这里的update和insert语句并不完整,因为实际还有where条件的存在,需要根据Primkey主键来拼接成一句完整的sql;另外的就是还有Model实体对象的合法性验证;

  • 相关阅读:
    thinkphp5分页
    thinkphp 获取器、修改器
    Thinkphp中对数据库的基础操作
    MYSQL 数据库内容的分页展示
    单例模式连接数据库
    简单的通过ajax ‘POST’ 方法实现与后台数据交互
    PHP中 .= 的意思
    mysqli 简单的php注册登录功能
    4.4
    梦断代码阅读笔记1
  • 原文地址:https://www.cnblogs.com/Francis-YZR/p/4770821.html
Copyright © 2011-2022 走看看