返回从具有泛型列表的接口派生的对象
本文关键字:接口 派生 对象 列表 泛型 返回 | 更新日期: 2023-09-27 18:11:34
我的应用程序从磁盘读取JSON并使用JSON.net进行反序列化;
我的JSON是这样布局的:
{
"driver": {
"driverTag": "blah_blah",
"driverName": "Blah Blah",
"driverTransport": "serial-device"
},
"devices": [
{
"deviceName": "Dev1",
"deviceTag": "DEV1",
"deviceStartMode": "Auto"
},
{
"deviceName": "Dev2",
"deviceTag": "DEV2",
"deviceStartMode": "Auto"
}
]
}
基于"driverTransport"的值,我反序列化为SerialDriverConfig, TelnetDriverConfig, SNMPDriverConfig…等类。
由于"driver"属性对于每个驱动程序都是相同的,无论传输类型如何,我有一个"DriverConfigTemplate"类。"设备"将因JSON文件而异,并且具有特定的传输类型属性(例如,串行设备将具有"serialPortName","serialBaudRate"等属性)
我有一个"DriverConfig"接口,其中T是"DeviceConfig"。
public interface DriverConfig<T> where T : DeviceConfig
{
DriverConfigTemplate driver { get; set; }
List<T> devices { get; set; }
}
设备配置如下:
public class DeviceConfig : IDeviceConfig
{
public string deviceTag { get; set; }
public string deviceName { get; set; }
public string deviceStartMode { get; set; }
}
;问题部分。当我反序列化时,我事先检查传输类型并确定要使用的类;例如,对于串行驱动程序,我将使用"SerialDriverConfig"类并使用"SerialDeviceConfig"进行反序列化:
public class SerialDeviceConfig : DeviceConfig
{
public int serialComPort { get; set; }
public int serialBaudRate { get; set; }
public int serialDataBits { get; set; }
public string serialParity { get; set; }
public string serialStopBits { get; set; }
public string serialHandshake { get; set; }
public int serialReadTimeout { get; set; }
public int serialWriteTimeout { get; set; }
public bool serialRtsEnable { get; set; }
public bool serialDtrEnable { get; set; }
}
我的"SerialDriverConfig"类是这样的:
public class SerialDriverConfig : DriverConfig<SerialDeviceConfig>
{
public DriverConfigTemplate driver { get; set; }
public List<SerialDeviceConfig> devices { get; set; }
}
同样,这很好,JSON.net反序列化器完美地完成了它的工作。
我有一个函数,当JSON配置文件被加载并对其各自的模式进行验证时调用,然后传递给"DeserialiseDriverConfig"函数,我试图返回派生的驱动程序对象;这就是我卡住的地方:(
private DriverConfig<DeviceConfig> DeserialiseDriverConfig(string _json, string _driverTransport)
{
switch (_driverTransport)
{
case "serial-device":
try
{
SerialDriverConfig _serialDriverConfig = JsonConvert.DeserializeObject<SerialDriverConfig>(_json);
if (_serialDriverConfig != null)
{
return _serialDriverConfig;
}
}
catch (Exception e)
{
//Blah blah blah
}
break;
}
return null;
}
我已经在这个问题上困了几天了,尝试了很多东西,这就是我结束的地方。我得到"不能隐式转换类型"SerialDriverConfig"到"DriverConfig"。存在显式转换(您是否错过了强制转换?)"所以我理解为什么这个错误发生,但无法绕过它。
希望我的代码是有意义的,有人可以帮助我在这里?
您可以将DriverConfig
类更改为非泛型
public interface DriverConfig
{
DriverConfigTemplate driver { get; set; }
List<DeviceConfig> devices { get; set; }
}
,而不是使用派生类(SerialDriverConfig
等),你可以设置Json.net反序列化到正确的DeviceConfig
类型基于有一个$type
属性在你的JSON像这样或使用自定义的JsonConverter
类似于这个
我不确定这个解决方案是否适合你的需要,但是如果你使用泛型T创建你的方法和SerialDriverConfig,你可以使用你的接口作为返回类型。你可以试试下面的代码;
方法:
private static DriverConfig<T> DeserialiseDriverConfig<T>(string _json, string _driverTransport)
{
switch (_driverTransport)
{
case "serial-device":
try
{
SerialDriverConfig<T> _serialDriverConfig = JsonConvert.DeserializeObject<SerialDriverConfig<T>>(_json);
if (_serialDriverConfig != null)
{
return _serialDriverConfig;
}
}
catch (Exception e)
{
//Blah blah blah
}
break;
}
return null;
}
SerialDriverConfig类:
public class SerialDriverConfig<T> : DriverConfig<T>
{
public DriverConfigTemplate driver { get; set; }
public List<T> devices { get; set; }
}
你也应该考虑改变DriverConfig<T>
接口方法,因为如果你让它保持原样,你会有装箱问题。如果您不需要,您可以从您的界面中删除where T : DeviceConfig
或根据您当前的情况修改它。
希望这对你有帮助,如果这对你有用,请告诉我