.net类型反射与晚期绑定

概念

以下仅指.NET中的概念

  • 类型:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
  • 反射:程序可以访问、检测和修改它本身状态或行为的一种技术。
  • 晚期绑定:在程序运行时,创建一个给定类型的实例,并在运行时调用其成员,而不需要在编译时知道它存在的一种技术。

在理解这些概念之前,最好了解程序集。程序集清单会列出程序集引用的外部程序集和资源,早期绑定的对象只能是内部对象和引用的外部程序集对象。如果想要绑定未引用的外部程序集(可能很难理解这种行为,但它确实在某些方面存在需求,比如工厂模式中创建的对象如果是程序集),只能通过反射技术。

例子

下面这个类(下文中称作ASS类)可以加载外部程序集,显示它的一些信息,同时它的静态函数也能显示一个已有类型的信息。

    public class AssemblyInfo
    {
        private Assembly ass;
        public AssemblyInfo(string assemblyURL)
        {
            ass = Assembly.LoadFrom(assemblyURL);
        }
        /// <summary>
        /// 获取当前程序集
        /// </summary>
        /// <returns></returns>
        public Assembly GetAssembly() { return ass; }
        
        /// <summary>
        /// 获取指定类型中的字段
        /// </summary>
        /// <param name="t"></param>
        public static string ListFields(Type t)
        {
            string retVal = "\n>>>>Fileds\n";
            var fieldNames = from f in t.GetFields() select f.Name;
            foreach (var fd in fieldNames)
            {
                retVal += string.Format("->{0}\n", fd);
            }
            return retVal;
        }
        /// <summary>
        /// 获取指定类型中的属性
        /// </summary>
        /// <param name="t"></param>
        public static string ListProps(Type t)
        {
            string retVal = "\n>>>>Properties\n";
            var propNames = from f in t.GetProperties() select f.Name;
            foreach (var pr in propNames)
            {
                retVal += string.Format("->{0}\n", pr);
            }
            return retVal;
        }
        /// <summary>
        /// 获取指定类型中的方法
        /// </summary>
        /// <param name="t"></param>
        public static string ListMethod(Type t)
        {
            string retVal = "\n>>>>Methods\n";
            var mts = t.GetMethods();
            foreach (var mt in mts)
            {
                string _retVal = mt.ReturnType.FullName;
                string paraInfo = "(";
                foreach (var pi in mt.GetParameters())
                {
                    paraInfo += string.Format("{0} {1}", pi.ParameterType, pi.Name);
                }
                paraInfo += ")";
                retVal += string.Format("->{0} {1} {2}\n", _retVal, mt.Name, paraInfo);
            }
            return retVal;
        }
        /// <summary>
        /// 显示程序集的信息
        /// </summary>
        /// <returns></returns>
        public string showInfo()
        {
            string retVal = "";
            var tps = ass.GetTypes();
            foreach (var tp in tps)
            {
                retVal += string.Format("\n****AssemblyName: {0}",tp.Name);
                retVal += ListFields(tp) + ListProps(tp) + ListMethod(tp);
            }
            return retVal;
            
        }
    }

查看系统类型的信息

用它来显示Int结构的信息:

        static void Main(string[] args)
        {
            Type t = typeof(int);
            System.Console.Write(AssemblyInfo.ListFields(t));
            System.Console.Write(AssemblyInfo.ListProps(t));
            System.Console.Write(AssemblyInfo.ListMethod(t));
            System.Console.ReadLine();
        }

运行之后可以看到int结构中的信息,可以与int的元数据对照查看,增加印象。

加载外部程序集

前一篇文章,编译生成了一个MathFunctions.dll,把它复制到本篇博客项目的bin下,这样可以直接通过ASS类来加载,只需要写一个程序集名,而不需要路径,调用的main方法如下:

        static void Main(string[] args)
        {
            string asName = "";
            do 
            {
                System.Console.WriteLine("\n请输入程序集名(包括路径):");
                asName = System.Console.ReadLine();
                if (asName.ToUpper()=="Q")
                {
                    break;
                }
                //检测程序集是否存在
                if (!File.Exists(asName))
                {
                    System.Console.WriteLine(asName + "不存在");
                    continue;
                }
                //读取程序集信息
                var ass = new AssemblyInfo(asName);
                //显示程序集信息
                System.Console.Write(ass.showInfo());
            } while (true);         
        }

在弹出的控制台界面中输入“MathFunctions.dll”,回车后即可看到此dll的内部定义。

晚期绑定

晚期绑定基于反射,前面只能看到未引用的外部程序集的定义,晚期绑定则实现调用外部程序集中的方法。(未完)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值