C # reflective assemblies

Assembly

Compiling the code assembly is a logical unit, and the relevant type code combining, then generating a PE file. Assembly only logical division, an assembly may be composed of only one file, multiple files may also be. Whether single or multi-file assembly file assembly, which consists of fixed structures

Two common Assembly:

  Executable file (.exe files) and library files (.dll files).

In the VS development environment, a solution can contain multiple items, and each item is an assembly.

Application structure:

  Comprising the application domain (AppDomain), the assembly (Assembly), the module (Module), type (Type), a member (EventInfo, FieldInfo, MethodInfo, PropertyInfo) several levels

Is an affiliation between them, that is to say, a AppDomain can include N Assembly, an Assembly can include N Module, a Module can include N Type, a Type can include N members. They are in the System.Reflection namespace. [ Common language runtime CLR ] loader manager application domain, such management including the loading of each assembly to the appropriate application domain, and a control assembly for each type of layout memory hierarchy

[] From the application structure is easy to see the assembly consisting Assembly:

MemberInfo class is a base class that defines the behavior of a plurality of common EventInfo, FieldInfo, MethodInfo, PropertyInfo of 

After a program up and running, there is an application domain (AppDomain), put all the assemblies we use (Assembly) in this application domain (AppDomain) in. All the code we write will be compiled into the [assembly] files (.exe .dll) in, and when to run [Assembly object] way to load into memory to run, each class (Class Interface) objects to [Type] way to load into memory, members of a class (methods, fields, is a property, event, constructors) are also loaded into memory corresponding object.

Details: https://www.cnblogs.com/luna-hehe/p/10143748.html

Assembly of the structure:

Assembly metadata, metadata types, the MSIL code resources.

assembly metadata , assembly metadata, also known as inventory, which recorded a lot of important information for an assembly, the assembly is to be the core document self-explanatory. When the program runs, CLR through this list will be able to obtain all the information necessary to run the assembly. The main list mainly includes the following information: identification information (including the name of the assembly, version, culture, and public key, etc.); a list of files (files that constitute the assembly); other programs referenced assembly list (the referenced assembly set); a permission request set (run the assembly needs permission).

type metadata , metadata type include the type of information contained in the assembly, the assembly details which classes are defined, which contains the properties and methods for each class, which each method parameter and return value type, etc. Wait.

MSIL codes , type of assembly metadata and metadata instructions of just some auxiliary information, which are described as MSIL code exists. MSIL code is the real core of the assembly, and they've realized the function of the assembly. For example, in "Animals" project, C # code is five animal ultimately are converted to MSIL code, save in the assembly Animals.dll, when you run the program, is drawn through these images of animals MSIL code.

resources , the assembly may also include images, icons, sounds and other resources.

Private assemblies and shared assemblies

Private assembly is an assembly only a single use of the software, installation is very simple, just copy the private assemblies to the folder where the files in the package can be. Those programs are jointly used by different software is shared assemblies, .NET class library assembly is shared assembly, shared assembly is common to the different programs, so it would not deploy private assemblies so simple, you must consider naming conflicts and version conflicts. Solution to these problems is the shared assembly on a specific file system folder, the specific folder called the Global Assembly Cache (GAC). This process can be completed specialized .NET tools

Characteristics of the assembly

// 将 ComVisible 设置为 false 使此程序集中的类型对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,则将该类型上的 ComVisible 属性设置为 true。
[assembly: ComVisible(false)]

// 如果此项目向 COM 公开,则下列 GUID 是用于类型库的 ID
[assembly: Guid("816a1507-8ca5-438d-87b4-9f3bef5b2481")]

// 程序集的版本信息由下面四个值组成:主版本、次版本、内部版本号、修订号
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

程序集的属性信息是由特性实现的,与普通特性的不同的是,描述程序集的特性前要添加前缀“assembly:”

原文链接:https://www.cnblogs.com/Sweepingmonk/p/10867975.html

Assembly 程序集对象

Assembly 是一个抽象类,我们用的都是RuntimeAssembly的对象。

获得程序集的方式:

  • 获得当前程序域中的所有程序集
    • Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
    • 所有用到过得aessembly。如果只是add ref了,没有在程序中用到,AppDomain.CurrentDomain.GetAssemblies()中没有。用到时才被JIT加载到内存。
    • 每个app都有一个AppDomain,OS不允许其他app访问这个程序的AppDomain
  • 获得当前对象所属的类所在的程序集
    • this.GetType().Assembly;
    • Type对象肯定在一个assembly对象中
    • 可以通过Type对象得到程序集
  • 根据路径加载程序集

    • Assembly.LoadFrom(assPath);
Assembly assembly = Assembly.LoadFrom(@"E:\Work\VSCode\ConsoleApp1\ClassLibrary1\bin\Debug\netstandard2.0\ClassLibrary1.dll");
Type[] allTypes = assembly.GetTypes();
Type stu = assembly.GetType("ClassLibrary1.Student");
object stu1 = Activator.CreateInstance(stu);
Console.WriteLine(stu1);

Type 类型对象

Type 是一个抽象类,我们用的都是TypeInfo类的对象。

程序运行时,一个class对应一个Type类的对象。通过Type对象可以获得类的所有信息。

获得Type对象的方式:

  • 通过类获得对应的Type
    • Type t1 = typeof(Person);
  • 通过对象获得Type用assembly对象,通过类的full name类获得type对象
    • Type t2 = person.GetType();  
    • this.GetType();
    • Type stu = assembly.GetType("ClassLibrary1.Student");
  • 获得程序集中定义的所有的public类

    • Type[] allPublicTypes = ass1.GetExportedTypes();
  • 获得程序集中定义的所有的类

    • Type[] allTypes = ass1.GetTypes();

Type类的属性:

  • t.Assembly; 获取t所在的程序集

  • t.FullName; 获取t所对应的类的full name

  • t.Name; 获取t所对应的类的 name

  • t.IsArray; 判断t是否是一个数组类

  • t.IsEnum; 判断t是否是一个枚举类

  • t.IsAbstract; 判断t是否是一个抽象类

  • t.IsInterface; 判断t是否是一个interface

Type类的方法:

  • notebookInterfaceType.IsAssignableFrom(Type t);判断t是否实现了 notebookInterfaceType 接口

  • t.IsSubclassOf(Type parent); t是否是parent的子类

  • t.IsInstanceOfType(object o); o是否是t类的对象

  • t.GetFields();  //method, property  得到所有的public的fields,methods,properties

Type类示例:

static void TypeTest1()
        {
            Person p = new Person { Name = "NaNa", Age = 5 };
            Type typePerson = p.GetType();

            //搜索具有指定名称的公共属性
            PropertyInfo pf = typePerson.GetProperty("Name");
            pf.SetValue(p, "LiLi", null);
            Console.WriteLine(p.Name);

            //返回所有公共属性
            PropertyInfo[] props = typePerson.GetProperties();
            StringBuilder builder = new StringBuilder(30);
            foreach (PropertyInfo item in props)
            {
                builder.Append(item.Name + "=" + item.GetValue(p, null) + "\n");
            }
            builder.Append("----------------------\n");

            //返回所有公共字段
            FieldInfo[] fieIds = typePerson.GetFields();
            foreach (FieldInfo item in fieIds)
            {
                builder.Append(item.Name + "=" + item.GetValue(p) + "\n");
            }
            builder.Append("----------------------\n");

            //返回所有公共方法
            MethodInfo[] methods = typePerson.GetMethods();
            foreach (MethodInfo item in methods)
            {
                builder.Append(item + "\n");
            }
            builder.Append("----------------------\n");
            Console.WriteLine(builder);

            //返回所有公共构造函数
            ConstructorInfo[] cons = typePerson.GetConstructors();
            foreach (ConstructorInfo item in cons)
            {
                //Name都是 .ctor  
                Console.WriteLine(item.Name + "\n");
                //构造函数的参数个数  
                Console.WriteLine(item.GetParameters().Length + "\n");

                ParameterInfo[] parames = item.GetParameters();
                foreach (var pars in parames)
                {
                    Console.WriteLine(pars.Name+""+pars.ParameterType);
                }
            } 
        }
View Code

原文链接:https://blog.csdn.net/CJB_King/article/details/80521481

反射概念:

1. 在程序运行时动态获取类或对象的信息,具体包括了

动态 获取 加载程序集(Assmebly)

动态 获取 类型信息(如类、接口 等) - Type对象

动态 获取 类型的成员信息(如方法,字段,属性等);

2. 在运行时,动态创建类型实例(new),以及 调用 和 访问 这些 实例 成员;

.Net反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为.Net的反射机制。

.Net反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;

反射的用途
类型 作用
Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
Module 包含模块的程序集以及模块中的类等。还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
ConstructorInfo 构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用Type的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
MethodInfo
方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用Type的  GetMethods 或 GetMethod 方法来调用特定的方法。
FieldInfo 字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
EventInfo 事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
PropertyInfo 属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
ParameterInfo 参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等

在程序运行时,动态获取程序集:

class Program
    {
        static void Main(string[] args)
        {
            Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
            Person p = new Person();
            p.TestAssembly();

            Console.ReadKey();
        }
    }


class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        private int Id;
        public double Sum;

        public void Method1() { }
        private void Method2() { }

        public void TestAssembly()
        {
            Assembly ass = this.GetType().Assembly;
            Console.WriteLine(ass);
            Type[] types = ass.GetTypes();
            foreach (var item in types)
            {
                Console.WriteLine(item + "   (types)");
            }
            Type currentType = ass.GetType();
            Console.WriteLine(currentType);
            Type typeByFullName = ass.GetType("ConsoleApp2.Person");
            Console.WriteLine(typeByFullName);

            Type type = this.GetType();
            Console.WriteLine(type);
            MethodInfo[] methods = this.GetType().GetMethods();
            foreach (var item in methods)
            {
                Console.WriteLine(item + "    (methods)");
            }
            var members = this.GetType().GetMembers();
            foreach (var item in members)
            {
                Console.WriteLine(item);
            }
            var member = this.GetType().GetMember("Name");
            foreach (var item in member)
            {
                Console.WriteLine(item);
            }
            FieldInfo field = type.GetField("Sum");
            Console.WriteLine(field);
            PropertyInfo prop = type.GetProperty("Name");
            Console.WriteLine(prop);
        } 
    }
View Code

在程序运行时,动态创建 类型实例:在Person类中加下面4个方法,在Main中测试

class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            p.CreatePersonObject();

            Console.ReadKey();
        } 
    }



public void CreatePersonObject()
        {
            Type type = this.GetType();
            Person p = Activator.CreateInstance(type) as Person;
            Person p1 = Activator.CreateInstance<Person>();

            PropertyInfo prop = type.GetProperty("Name");
            prop.SetValue(p1, "toto",null);
            Console.WriteLine(p1.Name);

            MethodInfo method = type.GetMethod("SayHi");
            method.Invoke(p1, null);
            MethodInfo method1 = type.GetMethod("ShowNumber");
            object[] arrParams = { 13 };
            method1.Invoke(p1, arrParams);
            MethodInfo method2 = type.GetMethod("GetString");
            string retStr = method2.Invoke(p1, null).ToString();
            Console.WriteLine(retStr);
        }

        public void SayHi()
        {
            Console.WriteLine("Hiiiiiiiiiiii");
        }
        public void ShowNumber(int no)
        {
            Console.WriteLine(no);
        }
        public string GetString()
        {
            return "Hello";
        }
View Code

通过反射找出类型的构造函数,然后调用构造函数来获取实例引用

public static void GetConstructor()
        {
            Type tpdatetime = Type.GetType("System.DateTime", false);
            if (tpdatetime != null)
            {
                ConstructorInfo constructor = tpdatetime.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
                if (constructor != null)
                {
                    object instance = constructor.Invoke(new object[] { 2019, 12, 17, 16, 11, 24 });
                    if (instance != null)
                    {
                        PropertyInfo[] props = tpdatetime.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                        Console.WriteLine("以下是DateTime实例的属性值列表");
                        foreach (PropertyInfo item in props)
                        {
                            object objval = item.GetValue(instance,null);
                            Console.WriteLine("{0,-15}:{1}",item.Name,objval??string.Empty);
                        }
                    }
                }
            }
        }
View Code

原文链接:https://www.cnblogs.com/czx1/p/201413137070-com.html

通过反射调用类的私有成员:

Person p = new Person();
Type tPerson = p.GetType();
//得到私有字段的值:
FieldInfo privateField = tPerson.GetField("privateFields", BindingFlags.Instance | BindingFlags.NonPublic);
//设置私有成员的值:
privateField.SetValue(p, "修改后的私有字段值");
Console.WriteLine(privateField.GetValue(p));

//得到私有属性的值: 
PropertyInfo privateProp = tPerson.GetProperty("PrivateProperties", BindingFlags.Instance | BindingFlags.NonPublic);
//设置私有属性的值:
privateProp.SetValue(p, "修改后的私有属性值",null);
Console.WriteLine(privateProp.GetValue(p,null));

//调用私有方法
MethodInfo privateMethod = tPerson.GetMethod("SayHi", BindingFlags.Instance | BindingFlags.NonPublic);
privateMethod.Invoke(p, null); 

 

 

 

 

Guess you like

Origin www.cnblogs.com/zhaoyl9/p/12036037.html