当前位置:网站首页>关于C#的反射,你真的运用自如嘛?
关于C#的反射,你真的运用自如嘛?
2022-08-04 05:25:00 【丁小未】
前言
我们都知道反射在编程语言里是非常方便也是非常强大的,但或许有人会觉得在学习或者工作中用的可能并不是那么多,这对于刚入行不久的人而言的,我的理解是反射在写框架和写工具是用的比较多的。举个栗子:写一个Excel的表格编辑器,我们能够在控制台修改Excel里面的内容,或许有人会觉得这有啥难的,直接手撸对应的Model,如果哪一天策划手滑或者手贱修改了命名,或者增加/减少一列,那我们程序是不是也要跟着修改,因为我们保存数据或许是写死的字段名,如果全部通过反射,那就随便策划怎么折腾excel,我有反射神器,我不怕!至于为啥要写Excel的编辑器,或许有人会疑惑,我直接在Excel里面编辑修改不行嘛,这样策划要修改个数据然后要导出数据,然后在游戏里面跑,会比较麻烦,如果有对应的表格编辑器直接在游戏运行时就修改测试就很方便,如果是bool类型就给策划toggle选项,如果是枚举类型就弄个下拉框,如果是范围类型就给个Range,这样策划就不会填错,如果编辑器是基于反射做的,不是字段写死的,策划随便修改excel的字段都不会出问题。
反射获取属性
typeof(Animal).GetProperties()
反射获取/设置属性的值
获取值
properities[i].GetValue(a)
获取的值是object类型的,如果想要转成对应真实类型,然后调用对应类型的扩展方法可以通过if去一个个判断然后强转,还没想到特别方便的通用的转换方式,也有看到过Convert.ChangeType,但返回类型还是Object,不是我想要的,如果有人知道有更好的方式,还请留言告知。
设置值
properities[i].SetValue(a, object xxx)
反射调用字段的扩展方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace ConsoleApp1
{
public class Animal
{
public int ID { get; set; }
public string Name { get; set; }
}
public static class Extension
{
public static string GetStringValue(this int v)
{
return "我是Int类型:" + v;
}
public static string GetStringValue(this string v)
{
return "我是String类型:" + v;
}
}
class Program
{
static void Main(string[] args)
{
Animal a = new Animal() { ID = 1, Name = "mimi" };
var properities = typeof(Animal).GetProperties();
var thisassembly = typeof(Animal).Assembly;
for (int i = 0; i < properities.Length; i++)
{
var v = properities[i].GetValue(a);
foreach (var m in GetExtensionMethods(thisassembly, v.GetType()))
{
var vv = m.Invoke(null, new object[] { v });
Console.WriteLine(vv);
}
}
Console.Read();
}
//反射获取扩展方法
static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly,
Type extendedType)
{
var query = from type in assembly.GetTypes()
where type.IsSealed && !type.IsGenericType && !type.IsNested
from method in type.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == extendedType
select method;
return query;
}
}
}
我在一开始没用上述反射获取扩展方法时,直接用的xxx.GetType().GetMethod(“GetStringValue”)是获取不到这个扩展方法的,
至于为啥普通方式获取不到扩展方法,这个要看IL层的设计了,事实上一个类的扩展方法并不属于该类,而是属于定义他的静态类,之所以能够调用,是因为编译器做了手脚的缘故,编译器遇到这种状况就会调用静态类的方法,通过其IL就可以看到真实的调用情况。
更多反射相关的API
还是参考官方文档最丰富呀。
https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.propertyinfo?view=netframework-4.8#%E5%B1%9E%E6%80%A7
参考链接
https://codeday.me/bug/20170729/42358.html
更多精品文章
http://dingxiaowei.cn/
边栏推荐
- MySQL日期函数
- 动态规划总括
- C语言 -- 操作符详解
- MySQL date functions
- 7.16 Day22---MYSQL(Dao模式封装JDBC)
- C Expert Programming Chapter 4 The Shocking Fact: Arrays and Pointers Are Not the Same 4.5 Other Differences Between Arrays and Pointers
- 注意!软件供应链安全挑战持续升级
- 4.2 声明式事务概念
- The Road to Ad Monetization for Uni-app Mini Program Apps: Full Screen Video Ads
- canal实现mysql数据同步
猜你喜欢
利用Jenkins实现Unity自动化构建
Do you think border-radius is just rounded corners?【Various angles】
The symbol table
MySQL log articles, binlog log of MySQL log, detailed explanation of binlog log
CentOS7 —— yum安装mysql
嵌入式系统驱动初级【3】——字符设备驱动基础中_IO模型
npm报错Beginning October 4, 2021, all connections to the npm registry - including for package installa
Embedded system driver primary [3] - _IO model in character device driver foundation
CentOS7 - yum install mysql
canal实现mysql数据同步
随机推荐
day13--postman interface test
7.15 Day21---MySQL----索引
4.3 基于注解的声明式事务和基于XML的声明式事务
CentOS7 - yum install mysql
4.2 声明式事务概念
4.3 Annotation-based declarative transactions and XML-based declarative transactions
MySQL日期函数
Redis common interview questions
12. Paging plugin
CentOS7 —— yum安装mysql
力扣:63. 不同路径 II
梳理CamStyle、PTGAN、SPGAN、StarGAN
5个开源组件管理小技巧
[SemiDrive source code analysis] [MailBox inter-core communication] 47 - Analysis of RPMSG_IPCC_RPC mode limit size of single transmission and limit bandwidth test
About yolo7 and gpu
The symbol table
4.1 声明式事务之JdbcTemplate
Gartner 权威预测未来4年网络安全的8大发展趋势
数的划分之动态规划
leetcode 12. Integer to Roman numeral