当前位置: 首页 > news >正文

C#进阶1

C#进阶1

本文章主要介绍C#的进阶知识,如反射,特性....
参考视频链接

原码

文章目录

  • C#进阶1
  • 反射
    • 步骤
    • 泛型反射
      • 调用方法
    • 获取属性
  • 特性
    • 特性的定义
    • 步骤
      • 扩展枚举练习


反射

在 C# 中,反射(Reflection)是一种强大的机制,允许程序在运行时检查和操作类型、方法、属性等元数据。通过反射,你可以在运行时动态地创建对象、调用方法、访问属性,甚至修改类型的行为。反射在许多场景中非常有用

  • 反射思路:首先获取程序中的类,然后通过类再获取方法,参数,构造方法等
  • 在项目路径下的debug文件中,.dll是首先要获取的,因为他是程序一次编译形成的产物,相关信息都可以通过反射获取
    在这里插入图片描述

步骤

  • 加载dll dll是经过一次编译形成的文件

    Assembly assembly = Assembly.Load("2024_10_30_Project");
    
  • 获取类

    Type type = assembly.GetType("_2024_10_30_Project.Person");
    
  • 调用构造,创建实例

     //创建无参Person p = (Person)Activator.CreateInstance(type, true);p.say();//调用有参Object o = Activator.CreateInstance(type, new Object[] { "我要说话" });
    

泛型反射

  • 对于类的话,如果类中有泛型,那么在获取类的时候要制定泛型个数,然后说明泛型

      //调用泛型无参  `3表示三个泛型Type type2 = assembly.GetType("_2024_10_30_Project.Zhou`3");//说明泛型类型type2 = type2.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//创建Object o2 = Activator.CreateInstance(type2);
    

调用方法

  • 类中获取方法,所以得有类,先获取实例,然后进行方法的获取;方法获取要制定获取的方法名,如果不是泛型方法,在获取方法名的同时,指定方法参数类型,如果是泛型方法,就先获取方法名,然后再制定泛型参数,最后调用方法。

     //方法反射{MethodInfo method3 = type2.GetMethod("zMethod3", new Type[] { });method3.Invoke(o2, null);}{var method2 = type2.GetMethod("zMethod2", new Type[] { typeof(string), typeof(int) });method2.Invoke(o2, new object[] { "张三", 11 });}{//调用私有MethodInfo method1 = type2.GetMethod("zMethod1", BindingFlags.Instance | BindingFlags.NonPublic);method1.Invoke(o2, new object[] { "我是私有m1" });}{//调用泛型共有方法Assembly a1 = Assembly.Load("2024_10_30_Project");Type type1 = a1.GetType("_2024_10_30_Project.TestClaz`1");type1 = type1.MakeGenericType(new Type[] { typeof(int) });Object oo1 = Activator.CreateInstance(type1);MethodInfo me1 = type1.GetMethod("m1");var me2 =me1.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) });me2.Invoke(oo1, new object[] { 1, "张张", DateTime.Now });}{//调用泛型私有方法Assembly a1 = Assembly.Load("2024_10_30_Project");Type type1 = a1.GetType("_2024_10_30_Project.TestClaz`1");type1 = type1.MakeGenericType(new Type[] { typeof(int) });Object oo1 = Activator.CreateInstance(type1);MethodInfo me1 = type1.GetMethod("m2",BindingFlags.Instance|BindingFlags.NonPublic);var me2 = me1.MakeGenericMethod(new Type[] { typeof(string) });me2.Invoke(oo1, new object[] { 1, "私有" });}
    

获取属性

由于获取的方式都参不多,大家可自信查阅api

{Assembly a1 = Assembly.Load("2024_10_30_Project");Type type1 = a1.GetType("_2024_10_30_Project.TestClaz`1");type1 = type1.MakeGenericType(new Type[] { typeof(int) });Object oo1 = Activator.CreateInstance(type1);var pr = type1.GetProperties();foreach(var pro in pr){Console.WriteLine(pro.Name);if (pro.Name.Equals("age")){pro.SetValue(oo1, 11);//设置属性值}Console.WriteLine(pro.GetValue(oo1));}}

特性

特性类似于java中的注解,用于给元素添加额外的信息

特性的定义

  • 如需要自定义特性,需要继承Attribute,使用如果自定义特性包含Attribute,可省略

     class CustomerAttribute:Attribute
    {
    }
    
    [Customer]
    class Person
    {public static void say(){Console.WriteLine("我是特性说话了");}
    }
    

步骤

  • 声明自定义特性,定义属性和方法

    namespace AttriProject
    {class CustomerAttribute:Attribute{public string name { get; set; }public int age { get; set; }public void say(){Console.WriteLine("我是特性类");}}
    }
    
  • 然后在Person类上添加特性

      //初始化特性,给特性赋值[Customer(name ="张三",age =11)]class Person{[Customer]public string name { get; set; }public static void say(){Console.WriteLine("我是特性说话了");}}
    
  • 在Manager类声明方法,通过反射获取Person类的特性

      public static void show(){Type type = typeof(Person);//获取类typeif (type.IsDefined(typeof(CustomerAttribute), true)) //看类中是否包含特性{//获取类的特性实例CustomerAttribute customer = (CustomerAttribute)type.GetCustomAttribute(typeof(CustomerAttribute));Console.WriteLine($"{customer.age}-{customer.name}");customer.say();}PropertyInfo proin = type.GetProperty("name");if (proin.IsDefined(typeof(CustomerAttribute), true)) //看类中是否包含特性{//获取类的特性实例CustomerAttribute customer = (CustomerAttribute)proin.GetCustomAttribute(typeof(CustomerAttribute));customer.say();}}
    

扩展枚举练习

  • 定义自定义特性

     class CustomerAttribute:Attribute{private string _remark;public string Remark { get => _remark; set => _remark = value; }public CustomerAttribute(string remark){this._remark = remark;}
    }
    
  • 定义枚举,并在字段上标注特性

   enum CEnum{[CustomerAttribute("春天")]SPRING=1,[CustomerAttribute("夏天")]SUMMER =2,[CustomerAttribute("秋天")]AUTUMN =3,[CustomerAttribute("冬天")]WINTER =4}
  • 定义枚举扩展方法扩展方法为静态类中包含静态方法,静态方法参数用this标识,这样方法参数类型调用此方法,会自动进入该方法 扩展方法返回特性的属性值

        public static class RemarkExten{public static string GetRemark(this Enum en){var type = en.GetType();var field = type.GetField(en.ToString());if (field.IsDefined(typeof(CustomerAttribute), true)){var cu = (CustomerAttribute)field.GetCustomAttribute(typeof(CustomerAttribute));return cu.Remark;}return "";}}
    
  • 主方法调用

     static void Main(string[] args){Manager.show();CEnum c = CEnum.SPRING;var x = c.GetRemark();Console.WriteLine(x);//春天}
    
http://www.lryc.cn/news/473639.html

相关文章:

  • PHP如何对输出进行转义
  • Windows 10 安装Docker踩过的坑和解决-31/10/2024
  • 【应急响应】Linux植入恶意程序排查流程
  • 微信小程序app.js里面onLaunch里面的函数比page里面的onshow里面的方法后执行
  • 斐波那契时间序列,精准捕捉市场拐点 MT4免费公式源码!
  • 计算机的错误计算(一百四十)
  • JavaEE初阶---网络原理(四)--IP协议/DNS协议
  • LeetCode20:有效的括号
  • 简单介绍Class文件、Dex文件以及ELF文件
  • Vivo开奖了,劝退价。。
  • 鸿蒙打包hvigorw clean报错No npmrc file is matched in the current user folder解决
  • 无人机救援系统基本组成
  • git入门教程
  • AMBA:AHB_Slave_Mux的解析与HREADY、HREADYOUT
  • 初始Linux (2) : 权限
  • 在Mac下安装时间序列软件Hector
  • JVM1.8内存模型
  • windows C#-类型系统(上)
  • 【酷狗音乐】逆向登录参数分析
  • Jenkins面试整理-Jenkins Pipeline 是什么?
  • RHCE第三次实验
  • 基于LORA的一主多从监测系统_4G模块上巴法云
  • pip使用
  • Django ORM详解:外键使用(外键逻辑关联)与查询优化
  • 【Python】实战:使用input()从键盘获取一个字符串,判断这个字符串在列表中是否存在(函数体不能使用in),返回结果为True或False
  • 【YApi】接口管理平台
  • QNAP威联通NAS忘记密码怎么办?
  • MySQL FIND_IN_SET 函数详解
  • 【零售和消费品&厨房】厨房食材检测图像分割系统源码&数据集全套:改进yolo11-goldyolo
  • 自制田字格word