[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 分钟前
【上位机——WPF】App.xml和Application类简介
xml·开发语言·c#·wpf·上位机
LallanaLee1 分钟前
常见面试题
java·开发语言
bestcxx3 分钟前
c# UTC 时间赋值注意事项
c#·utc
酷炫码神6 分钟前
C#运算符
开发语言·c#
小秋学嵌入式-不读研版11 分钟前
C42-作业练习
c语言·开发语言·笔记
休息一下接着来17 分钟前
C++ 条件变量与线程通知机制:std::condition_variable
开发语言·c++·算法
小哈里37 分钟前
【pypi镜像源】使用devpi实现python镜像源代理(缓存加速,私有仓库,版本控制)
开发语言·python·缓存·镜像源·pypi
努力学习的小廉41 分钟前
【C++】 —— 笔试刷题day_29
开发语言·c++·算法
电商数据girl1 小时前
酒店旅游类数据采集API接口之携程数据获取地方美食品列表 获取地方美餐馆列表 景点评论
java·大数据·开发语言·python·json·旅游
天天打码1 小时前
python版本管理工具-pyenv轻松切换多个Python版本
开发语言·python