首页 > 其他分享 >反射和特性

反射和特性

时间:2022-11-24 11:44:26浏览次数:39  
标签:反射 Console Name 程序 System 特性 获取 WriteLine

反射

一个运行的程序查看本身的元数据或者其他程序集的元数据的行为叫做反射。

元数据,就是描述数据的数据。Metadata存在于任何对数据和数据关系的描述中,

  NET是基于面向对象的,所以元数据描述的主要目标就是面向对象的基本元素:类、类型、属性、方法、字段、参数、特性等,主要包括:
  ●定义表,描述了源代码中定义的类型和成员信息,主要包括:TypeDef、MehodDef、FieldDef、ModuleDef、PropertyDef等。
  ●引用表,描述了源代码中引用的类型和成员信息,引用元素可以是同一程序集的其他模块,也可以是不同程序集的模块,主要包括:AssemblyRef、TypeRef、ModuleRef、MethodsRef等。
  ●指针表,使用指针表引用未知代码,主要包括:MethodPtr、FieldPtr、ParamPtr等。
  ●堆,以stream的形式保存的信息堆,主要包括:#String、#Blob、#US、#GUIDe等。

  元数据是保存了类型的编译后数据,是.NET程序运行的基础,我们可以在运行时动态地以反射的方式获取元数据信息,而这些信息在.NET Framework中以System.Type、MethodInfo等封装。

程序集是 .net 应用程序的部署单元。.net应用程序包含一个或多个程序集。通常拓展名是exe或dll的 .net可执行文件被称为程序集。程序集包含了描述程序集的元数据

开发的代码(一个一个的类)经过编译后会编译成程序集(dll/exe),程序集可以在操作系统上运行,如果要查看自己的代码可以在开发工具上查看,但是要在程序运行过程中查看别的程序集(非自己开发,没有源代码),可以通过反射查看该类中包含的成员,当然也可以查看自己类中包含的成员。

   源代码生成程序集,使用反射技术,通过程序集查看包含的成员。

Type:每个类中都有一个对应的Type对象,保存了类中的信息,比如方法、成员等等。

namespace Reflections
{
    class MyClass
    {
        //成员变量,字段
        private int A;
        private string B;
        public int C;
        public string D;
        
        //属性        
        public string Name { get; set; }
        public int Number { get; set; }
        private int sex { get; set; }

        //方法
        public void Test1() { }
        public int Test2(int number) 
        {
            return number + 1;
        }
        private void x() { }
    }
}
class Program
    {
        static void Main(string[] args)
        {
            //Type获取方式
            Type t = typeof(MyClass); //方式一 通过类名获取

            MyClass myClass = new MyClass();
            Type type = myClass.GetType(); //方式二 通过类的对象获取

            Console.WriteLine(t.Name); //获取类名 MyClass
            Console.WriteLine(t.Namespace);//获取命名空间名 Reflections
            Console.WriteLine(t.Assembly);//获取程序集属性说明 Reflections, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
            Console.WriteLine("\n");
            //获取字段
            FieldInfo[] fis = t.GetFields();
            foreach(FieldInfo field in fis) //只能获取公有字段 field.Name 获取字段名称,field.FieldType 获取字段类型
            {
                Console.WriteLine(field.Name+" "+field.FieldType); // C System.Int32
                                                                   // D System.String
            }
            //获取属性
            PropertyInfo[] pas = t.GetProperties();
            foreach (PropertyInfo pro in pas) //只能获取公有属性 pro.Name 获取属性名称,pro.FieldType 获取属性类型
            {
                Console.WriteLine(pro.Name + " " + pro.PropertyType); // Name System.String
                                                                      //Number System.Int32
            }
            //获取方法
            MethodInfo[] mes = t.GetMethods();
            foreach (MethodInfo method in mes) //只能获取公有方法 method.Name 获取方法名称,method.ReturnType 获取方法返回类型
            {
                Console.WriteLine(method.Name + " " + method.ReturnType);
                 /* Test1 System.Void
                    Test2 System.Int32
                    GetType System.Type
                    ToString System.String
                    Equals System.Boolean
                    GetHashCode System.Int32    同时也可以获取到继承父类的方法
                 */
            }
        }
    }

加载程序集方法:

 

特性(类似批注)

系统特性:

Obsolete 弃用

Conditional("name") 条件特性,控制某一方法是否启用,与宏相对应。name为宏的名字。

#define IsShowMessage

定义了宏,所有调用该方法的地方都会被调用。

没有定义宏,所有调用该方法的地方都不会被调用。

调用者信息特性,用在参数上

调用者信息特性可以访问文件路径,代码行数,调用成员的名称等源代码信息。
  这三个特征名称分别为:
    CallerFilePath,CallerLineNumber, CallerMemberName
  这三个特性只用用于方法中的参数

//这三个参数是系统进行定义和传递的
static void PrintOut(string str,
    [CallerFilePath]string fileName = "", //初始化
    [CallerLineNumber]int lineNumber = 0, 
    [CallerMemberName]string methodName = "")
{
    Console.WriteLine(str);
    Console.WriteLine(fileName);
    Console.WriteLine(lineNumber);
    Console.WriteLine(methodName);
}

static void main()
{
    PrintOut("123");      //所在行为37行
}
//输出为:
//123
//C:\xx\xx\xx\xx\Program.cs         调用该方法的文件的路径名
//37                                调用该函数语句所在的行
//Main                              调动该方法的成员名称

 DebuggerStepThrough debug特性,在方法前面使用,debug调试时不会进入

也可以自定义特性。

 

标签:反射,Console,Name,程序,System,特性,获取,WriteLine
From: https://www.cnblogs.com/Joyce-mi7/p/16921347.html

相关文章

  • postgresql 14新特性
    再说PostgreSQL14之前,先来带大家回复一下之前发布的各个版本和特性。PostgreSQL9.0:支持64位windows系统,异步流数据复制、HotStandby;PostgreSQL9.1:支持数据同步复制......
  • 记录一些JDK的新特性~持续更新
    1、record快速定义类@TestpublicvoidtestRecord(){/***JDK16新特性**@paramstart*@paramend......
  • Java帝国的诞生、Java的特性、Java的版本
    Java帝国的诞生C&C++1972年C诞生贴近硬件、运行极快、效率极高操作系统,编译器,数据库,网络系统等指针和内存管理1982年C++诞生面向对象兼容C图形领域、游戏等J......
  • java8新特性
    什么是函数式(Functional)接口只包含一个抽象方法的接口,称为函数式接口。你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么......
  • 面向对象的三大特性
    ​ 面向对象的三大特性:封装:        我们把数据、一系列操作数据的函数封装到方法中,然后通过权限修饰符控制哪些方法可以让外知道,哪些只能自己知道,这样就能减少......
  • Java 反射
         反射=反向射击=Java向自己射击=Java对自身进行描述=Java用研究外部事物的方法反过来研究自己——反射的好处:1.可以在程序运行过程中,操作这些对象。2.......
  • Karmada跨集群优雅故障迁移特性解析
    摘要:在Karmada最新版本v1.3中,跨集群故障迁移特性支持优雅故障迁移,确保迁移过程足够平滑。本文分享自华为云社区《​​Karmada跨集群优雅故障迁移特性解析​​》,作者:Karma......
  • C#如何反射出委托的签名,反射调用委托
    本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下delegatedoubleFooDelegate(stringparam,boolcondition);那么我们怎么用反射知道这个委托......
  • 虚拟机软件VMware Fusion 13发布,增加了哪些新特性?
    macOS平台虚拟机软件VMwareFusion13Pro的正式版正式发布,新版本更新支持不少新特性,其中包括:支持macOSVentura13、支持虚拟TPM2.0模块与Windows11、支持在AppleSilico......
  • Java特性和优势
    简单性与C语言不同,Java是一种面向对象编程的语言,他的底层借鉴了C++语言但又不是完全相同,Java语言并不支持多继承、指针、goto语句、操作符重载、头文件等,但其语法基于C语......