[C#]反射的实战应用,实际数据模拟

csharp 复制代码
long? value = null;
// 看它是不是 HEX_STRING
var dtAttr = prop.GetCustomAttribute<DataTypeAttribute>();
if (dtAttr != null && dtAttr.DataType == DataType.HEX_STRING)
{
    // 去掉可能的 "0x" 前缀
    string txt = attribute.Value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
                 ? attribute.Value.Substring(2)
                 : attribute.Value;
    // 按十六进制解析
    if (long.TryParse(txt, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long hexResult))
        value = hexResult;
}
else
{
    // 按十进制解析
    if (long.TryParse(attribute.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long decResult))
        value = decResult;
}
  1. 遍历 XML 里每个属性(XAttribute),
  2. 反射 找到同名的 GlobalParameter 属性 (PropertyInfo),
  3. 根据那个属性上有没有标记 [DataType(DataType.HEX_STRING)] 来决定"按十六进制"还是"按十进制"解析它的字符串值,
  4. 最后用 prop.SetValue(...) 把解析出来的 long? 写回到 globalParameter 对象里。

关键解析

csharp 复制代码
var prop = type.GetProperty(attribute.Name.LocalName);
if (prop == null || !prop.CanWrite)
    continue;
  • typetypeof(GlobalParameter)attribute.Name.LocalName 比如 "P00A""P100"......

  • GetProperty("P00A") 就拿到 GlobalParameter.P00APropertyInfo

  • prop.CanWrite 确保它有公开的 setter,否则无需赋值。

  • GetCustomAttribute<DataTypeAttribute>() 读出你在属性上贴的 [DataType(DataType.HEX_STRING)]

  • 如果它是 HEX_STRING,就把字符串(可能以 "0x" 开头)切掉前缀,再用 NumberStyles.HexNumber 按 16 进制转成 long

  • 否则直接按 10 进制 NumberStyles.Integer 转。

csharp 复制代码
prop.SetValue(globalParameter, value);
pnNotExists = false;
  • 这一行最关键:等同于 动态执行 globalParameter.P00A = value;globalParameter.P100 = value;
  • .NET 在后台会调用对应属性的 set 方法,把刚刚解析好的 long? 写进去。

举例模拟

假设 XML 节点是:

xml 复制代码
<GlobalParameter
    P00A="0x000B"
    P100="2500"
/>
  • 第一次循环

    • attribute.Name = "P00A", attribute.Value = "0x000B"
    • prop 对应 GlobalParameter.Pn00A,它有 [DataType(HEX_STRING)]
    • 去前缀后 txt = "000B"TryParse(..., HexNumber)hexResult = 11
    • prop.SetValue(globalParameter, 11) ------ 相当于 globalParameter.P00A = 11;
  • 第二次循环

    • attribute.Name = "Pn100", attribute.Value = "2500"
    • prop 对应 GlobalParameter.P100,默认是 INT
    • TryParse("2500", Integer)decResult = 2500
    • prop.SetValue(globalParameter, 2500) ------ 相当于 globalParameter.P100 = 2500;

最后返回的 globalParameter 对象里,

csharp 复制代码
globalParameter.P00A == 11;   // 0x000B → 11
globalParameter.P100 == 2500; // 2500

正因为 SetValue 就是调用属性的 setter,所以新解析出来的值就"自动"存到那个实例里了。

相关推荐
知无不研1 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29142 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
wujian83113 小时前
怎么用千问生成word文档:从「格式崩」到「一键过」,AI导出鸭打通最后半厘米
人工智能·ai·c#·word·豆包·deepseek·ai导出鸭
C++ 老炮儿的技术栈3 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011163 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据3 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡4 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai4 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
瑞码空间4 小时前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing
小努蛋5 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty