You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中List<Sensor>转List<IntSensor/ExtSensor>技术问题求助

问题分析与解决方案

兄弟,我一眼就看出问题核心了——你在ParseJsonData.GetSensors方法里创建的全是基类Sensor的实例,而不是IntSensor或者ExtSensor的子类实例!这就好比你造了一堆普通轿车,现在想直接把它们当成跑车用,肯定行不通,因为它们从本质上就不是跑车类型。

为什么你之前的转换尝试全失败了?

  • Cast<IntSensor>():这个方法是强制把集合里的每个元素当成IntSensor,但你的元素实际类型是Sensor,类型不兼容,运行时会直接抛出InvalidCastException。
  • ConvertAll(instance => (IntSensor)instance):和Cast逻辑一致,强制转换基类实例为子类,同样会因为对象实际类型不匹配而失败。
  • OfType<IntSensor>():这个方法是筛选集合中本来就是IntSensor类型的元素,你的集合里全是Sensor,自然返回空列表。

方案一:解析时直接生成对应子类实例(推荐)

修改GetSensors方法,让它根据需求创建指定子类的实例,后续就不需要任何转换操作了。

修改后的ParseJsonData类:

public class ParseJsonData {
    public static Device GetRoomAlertModel(JObject jsonTree) {
        Device model = new Device();
        model.IP = jsonTree["ip"].ToString();
        model.Name = jsonTree["name"].ToString();
        return model;
    }
    
    // 泛型方法,直接创建指定子类的传感器实例
    public static List<T> GetSensors<T>(JToken jToken) where T : Sensor, new() {
        var sensors = new List<T>();
        try {
            foreach (var item in jToken) {
                var s = new T(); // 这里创建的是子类实例
                s.Name = item["lab"].ToString();
                s.ActualTemp = item["tf"] != null ? item["tf"].ToString() : "";
                s.HighTemp = item["hf"] != null ? item["hf"].ToString() : "";
                s.LowTemp = item["lf"] != null ? item["lf"].ToString() : "";
                sensors.Add(s);
            }
        } catch (Exception) { }
        return sensors;
    }
}

然后在仓储类中直接调用:

public class RoomAlertRepository {
    internal Device Retreive() {
        var filePath = HostingEnvironment.MapPath(@"~/App_Data/RoomAlertsData.json");
        var json = File.ReadAllText(filePath);
        JObject jsonTree = JObject.Parse(json);
        var internalSensorTree = jsonTree["internal_sen"];
        var externalSensorTree = jsonTree["sensor"];
        var model = ParseJsonData.GetRoomAlertModel(jsonTree);
        
        // 直接获取IntSensor列表,无需转换
        model.InternalSensors = ParseJsonData.GetSensors<IntSensor>(internalSensorTree);
        // 同理获取ExtSensor列表
        model.ExternalSensors = ParseJsonData.GetSensors<ExtSensor>(externalSensorTree);
        
        return model;
    }
}

方案二:手动映射基类属性到子类(兼容现有代码)

如果暂时不能修改GetSensors方法,你可以手动把基类对象的属性值复制到新的子类实例中,而不是直接强制转换:

仓储类中的代码修改为:

var baseList = ParseJsonData.GetSensors(internalSensorTree);
model.InternalSensors = baseList.Select(s => new IntSensor {
    Name = s.Name,
    ActualTemp = s.ActualTemp,
    HighTemp = s.HighTemp,
    LowTemp = s.LowTemp
}).ToList();

这种方式虽然需要逐个复制属性,但能解决当前问题,适合基类属性不多的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:48:01