You need to enable JavaScript to run this app. 温度计类OOP与struct代码结构是否合理?JSON如何反序列化到struct
优惠活动
大模型
产品
解决方案
定价
更多

温度计类OOP与struct代码结构是否合理?JSON如何反序列化到struct

问题1:当前OOP设计存在的缺陷

现有设计存在几个明显的不合理点:

  • 成员作用域错误:Thermometer构造函数中定义的_limits、_config、_measurements是构造函数局部变量,出了构造函数就会被销毁,类本身没有对应成员,外部根本无法访问赋值
  • 访问修饰符缺失:C#中struct、class的字段/属性默认是私有访问级别,你定义的所有struct字段没有加public修饰,序列化框架无法读写这些字段
  • 结构扩展性极差:Limits结构体把时段写死成内嵌struct,后续如果要新增时段(比如早9点)必须修改struct定义,完全可以优化为通用的时段阈值结构+字典存储,适配任意时段需求
  • 无类型安全:使用dynamic做反序列化没有编译期类型检查,运行时容易出现类型不匹配的隐式错误
问题2:赋值失败的解决方案

赋值失败的核心原因是:dynamic反序列化得到的是Newtonsoft.Json的JObject类型,无法隐式转换为自定义的Limits值类型,再加上前面提到的成员作用域、访问修饰符问题,最终赋值报错。
你可以按照以下步骤修复:

步骤1:修正类型定义

// 通用时段阈值结构,复用在所有时段上
public struct TimeLimit
{
    public double Min { get; set; }
    public double Max { get; set; }
}

public struct CONFIG
{
    public bool inShadeorInSun { get; set; }
    public string Thermometer_Model { get; set; }
    public string Location { get; set; }
}

// 兼容原有JSON结构的Limits定义
public struct Limits
{
    public TimeLimit sevenPM { get; set; }
    public TimeLimit twelvePM { get; set; }
    public TimeLimit threePM { get; set; }
}

// 如果需要支持任意时段,可以换成字典实现
// public struct Limits
// {
//     public Dictionary<string, TimeLimit> TimeRangeLimits { get; set; }
// }

public struct Measurements
{
    public double sevenPM { get; set; }
    public double twelvePM { get; set; }
    public double threePM { get; set; }
}

// 修正Thermometer类的成员定义
public class Thermometer
{       
    // 定义为类的公共属性,外部可访问
    public Limits Limits { get; set; }
    public CONFIG Config { get; set; }
    public Measurements Measurements { get; set; }

    public Thermometer()
    {
        Limits = new Limits();
        Config = new CONFIG();
        Measurements = new Measurements();
    }               
    
    public void Method1()
    {
        // 业务逻辑
    }
    
    public void Method2()
    {
        // 业务逻辑
    }   
}

步骤2:修正反序列化赋值逻辑

using Newtonsoft.Json.Linq;

// 读取JSON文件
string json = File.ReadAllText("Limits.json");
JObject allLimits = JObject.Parse(json);
// 取对应设备的阈值节点,显式转换为Limits类型
Limits thermo2Limits = allLimits["Thermometer2"].ToObject<Limits>();
// 赋值
Thermometer _thermometer2 = new Thermometer();
_thermometer2.Limits = thermo2Limits;

内容的提问来源于stack exchange,提问作者Breakwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 11:45:02