[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,所以新解析出来的值就"自动"存到那个实例里了。

相关推荐
安冬的码畜日常16 分钟前
【AI 加持下的 Python 编程实战 2_10】DIY 拓展:从扫雷小游戏开发再探问题分解与 AI 代码调试能力(中)
开发语言·前端·人工智能·ai·扫雷游戏·ai辅助编程·辅助编程
朝阳58138 分钟前
Rust项目GPG签名配置指南
开发语言·后端·rust
朝阳58139 分钟前
Rust实现高性能目录扫描工具ll的技术解析
开发语言·后端·rust
程高兴40 分钟前
基于Matlab的车牌识别系统
开发语言·matlab
牛马baby1 小时前
Java高频面试之并发编程-07
java·开发语言·面试
CodeWithMe1 小时前
【C++】STL之deque
开发语言·c++
炯哈哈2 小时前
【上位机——MFC】运行时类信息机制
开发语言·c++·mfc·上位机
T.Ree.3 小时前
【数据结构】_树和二叉树
c语言·开发语言·数据结构
电商api接口开发4 小时前
ASP.NET MVC 入门指南
c#·asp.net·mvc
夜夜敲码4 小时前
C语言教程(十五):C 语言函数指针与回调函数详解
c语言·开发语言