• 元数据与反射(二)


    1.反射程序集

      获取Assmbly对象有以下方法:

     (1)Assmbly.Load("程序集文件名称")

    Assembly assembly = Assembly.Load("类库Demo");

    (2)Assmbly.LoadFrom("程序集文件名")

    Assembly assembly = Assembly.LoadFrom("类库Demo.dll");

    上述两个方法的区别就在于Load只需要提供文件名不加后缀的信息即可。
    (3)反射当前的程序集 Assmbly.GetExecutingAssembly()

    Assembly assembly = Assembly.GetExecutingAssembly();

    值得注意的是,对于引用同一解决方案的其他项目生成的程序集,Load和LoadFrom只需要提供程序集名就可以了,但是对于非本解决方案下得程序集,则需要提供程序集的完整路径了。

               Assembly assembly2 = Assembly.LoadFrom(@"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5System.dll");
     

    否则会报以下错误:

    2.程序集中的成员信息与MemberInfo类型

    代码如下图

    public class Program
        {
            static void Main(string[] args)
            {
                Assembly assembly = Assembly.Load("类库Demo");
                Module[] moudles = assembly.GetModules();//一个程序集中有多个模块(可以理解为多个独立的文件)
                foreach (var moudle in moudles)
                {
                    Console.Write("Moudle名称:"+moudle.Name);
                    Type[] types = moudle.GetTypes();//一个模块又有多个类型(可以理解为一个类文件中又有多个类、接口、枚举、委托等)
                    foreach (var type in types)
                    {
                        Console.WriteLine("Type名称:"+type.Name+"
    ");
                        PrintTypeInfo(type);
                        Console.WriteLine("**************************" + "
    ");
                    }
                    Console.WriteLine("================="+"
    ");
                }
                Console.ReadKey();
            }
    
            static void PrintTypeInfo(Type t)
            {
                MemberInfo[] memberInfos = t.GetMembers();
                foreach (var memberInfo in memberInfos)
                {
                    //根据memberInfo.MemberType来输出类型
                    Console.WriteLine("名称:"+memberInfo.Name+"     类型"+memberInfo.MemberType+"
    ");
                }
            }
        }

    ”类库Demo”中包含了以下代码:包含了类、接口、委托、事件、属性、字段、方法等信息

    public class ClassLabiry
        {
            public string OtherInfo { get; set; }
    
            public void PrintOtherInfo()
            {
                Console.WriteLine(OtherInfo);
            }
        }
        public abstract class FatherClass
        {
    
        }
    
        public struct structDemo
        {
    
        }
    
        public delegate void MyDelegate(string name);
    
        public enum Day
        {
            monday=1,
            sunday=2
        }
    
        public interface IDemoInterfaceOne
        {
            void SayHello();
        }
    
        public interface IDemoInterfaceTwo
        {
        }
    
        public sealed class DemoClass : FatherClass, IDemoInterfaceOne, IDemoInterfaceTwo
        {
            private string name;
            public string city;
            public readonly string title;
            public const string text = "Const Field";
            public event MyDelegate myEvent;
    
            public string Name
            {
                private get { return name; }
                set { name = value; }
            }
    
            public DemoClass()
            {
                title = "Readonly Field";
            }
    
            public class NestedClass
            {
            }
    
            public void SayHello()
            {
                Console.WriteLine("Good Morning" + name);
            }
        }

    输出的结果为:

    Moudle名称:类库Demo.dllType名称:ClassLabiry
    名称:get_OtherInfo     类型Method
    名称:set_OtherInfo     类型Method
    名称:PrintOtherInfo     类型Method
    名称:ToString     类型Method
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:GetType     类型Method
    名称:.ctor     类型Constructor
    名称:OtherInfo     类型Property
    **************************
    Type名称:FatherClass
    名称:ToString     类型Method
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:GetType     类型Method
    **************************
    Type名称:structDemo
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:ToString     类型Method
    名称:GetType     类型Method
    **************************
    Type名称:MyDelegate
    名称:Invoke     类型Method
    名称:BeginInvoke     类型Method
    名称:EndInvoke     类型Method
    名称:GetObjectData     类型Method
    名称:Equals     类型Method
    名称:GetInvocationList     类型Method
    名称:GetHashCode     类型Method
    名称:DynamicInvoke     类型Method
    名称:get_Method     类型Method
    名称:get_Target     类型Method
    名称:Clone     类型Method
    名称:ToString     类型Method
    名称:GetType     类型Method
    名称:.ctor     类型Constructor
    名称:Method     类型Property
    名称:Target     类型Property
    **************************
    Type名称:Day
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:ToString     类型Method
    名称:ToString     类型Method
    名称:CompareTo     类型Method
    名称:ToString     类型Method
    名称:ToString     类型Method
    名称:HasFlag     类型Method
    名称:GetTypeCode     类型Method
    名称:GetType     类型Method
    名称:value__     类型Field
    名称:monday     类型Field
    名称:sunday     类型Field
    **************************
    Type名称:IDemoInterfaceOne
    名称:SayHello     类型Method
    **************************
    Type名称:IDemoInterfaceTwo
    **************************
    Type名称:DemoClass
    名称:add_myEvent     类型Method
    名称:remove_myEvent     类型Method
    名称:set_Name     类型Method
    名称:SayHello     类型Method
    名称:ToString     类型Method
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:GetType     类型Method
    名称:.ctor     类型Constructor
    名称:Name     类型Property
    名称:myEvent     类型Event
    名称:city     类型Field
    名称:title     类型Field
    名称:text     类型Field
    名称:NestedClass     类型NestedType
    **************************
    Type名称:NestedClass
    名称:ToString     类型Method
    名称:Equals     类型Method
    名称:GetHashCode     类型Method
    名称:GetType     类型Method
    名称:.ctor     类型Constructor
    **************************
    =================

    3.BindFlag对检索对象可访问性的过滤

    上面的DemoClass 中私有字段name并没有被打印出来,其实是因为在获取Member成员时有BindFlag的过滤。BindFlag是一个枚举类型,给检索加上了条件。

    用法如下:

    MemberInfo[] memberInfo = t.GetMembers(
    BindingFlags.Public |
    BindingFlags.Static |
    BindingFlags.NonPublic |
    BindingFlags.Instance |
    BindingFlags.DeclaredOnly
    )

    对于私有字段访问,上面的代码可以改为:

    MemberInfo[] memberInfos = t.GetMembers(
    BindingFlags.NonPublic |
    BindingFlags.Instance );

    本以为NonPublic一个就可以了,不知道为啥实验了几次这两个出现才打印出来,得找找资料再看看了。

    另外还可以配合MemberTypes枚举进行类型的过滤,如下

    MemberInfo[] memberInfos = t.FindMembers(
                    MemberTypes.Method, // 说明查找的成员类型为 Method
                    BindingFlags.Public |
                    BindingFlags.Static |
                    BindingFlags.NonPublic |
                    BindingFlags.Instance |
                    BindingFlags.DeclaredOnly,
                    Type.FilterName,
                    "*");

    Type.FilterName表示一个委托,该委托用于筛选 System.Reflection.MemberInfo 对象数组中表示的成员列表。,最后一个参数“*”,说明返回所有方法(如果使用"Print*",则会返回所有以Print开头的方法)。

    MemberInfo[] memberInfos = t.FindMembers(
                    MemberTypes.Method, // 说明查找的成员类型为 Method
                    BindingFlags.Public |
                    BindingFlags.Static |
                    BindingFlags.NonPublic |
                    BindingFlags.Instance |
                    BindingFlags.DeclaredOnly,
                    Type.FilterName,
                    "Print*");

  • 相关阅读:
    表单
    超链接
    图像
    表格
    排列清单控制标
    HTML基本结构
    如何快速查看网页源代码
    TOR的使用
    google搜索新姿势
    [NOIP2017]列队
  • 原文地址:https://www.cnblogs.com/yanglaosan/p/6686318.html
Copyright © 2020-2023  润新知