[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;
  • type 是 typeof(GlobalParameter),attribute.Name.LocalName 比如 "P00A"、"P100"......

  • GetProperty("P00A") 就拿到 GlobalParameter.P00A 的 PropertyInfo。

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

相关推荐
死磕音视频5 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲8 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧8 小时前
C#:输入的字符串格式不正确
c#
程序喵大人10 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)10 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的10 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质11 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄62311 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_9628857212 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python