返回从具有通用列表

时间:2016-10-04 06:23:54

标签: c# generics

我的应用程序从磁盘读取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 ......等类。

作为"驱动程序"对于每个驱动程序,属性都是相同的,无论运输类型如何,我都有一个" DriverConfigTemplate"类。 "设备"将从JSON文件到JSON文件不同,并具有该传输类型的特定属性(即,串行设备将具有类似" serialPortName"," serialBaudRate&#34等属性)

我有一个" 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; }
}

现在;问题部分。当我反序列化时,我会事先检查传输类型并确定要使用的类;即对于串行驱动程序,我将使用&#34; SerialDriverConfig&#34;使用&#34; SerialDeviceConfig&#34;:

进行类和反序列化
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; }
}

我的&#34; SerialDriverConfig&#34; class看起来像这样:

public class SerialDriverConfig : DriverConfig<SerialDeviceConfig>
{
    public DriverConfigTemplate driver { get; set; }
    public List<SerialDeviceConfig> devices { get; set; }
}

同样,这很好,JSON.net deserialiser完美地完成了它的工作。

我有一个函数,当JSON配置文件已根据其各自的模式加载和验证时被调用,然后传递给&#34; DeserialiseDriverConfig&#34;函数我试图返回派生的驱动程序对象;这就是我陷入困境的地方:(

 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;
    }

我已经坚持了几天,已经尝试了很多东西,这就是我最终的结果。我得到&#34;无法隐式转换类型&#34; SerialDriverConfig&#34; to&#34; DriverConfig&#34;。存在显式转换(您是否错过了演员?)&#34;所以我理解为什么会出现这种错误,但无法绕过它。

希望我的代码有意义,有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

我不确定此解决方案是否符合您的需求,但如果您使用泛型类型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或根据您当前的情况进行修改。

希望这有帮助,如果这对您有用,请告诉我

答案 1 :(得分:1)

您可以将DriverConfig课程更改为非通用

public interface DriverConfig 
{
    DriverConfigTemplate driver { get; set; }
    List<DeviceConfig> devices { get; set; }
}

而不是使用派生类(SerialDriverConfig等),您可以将Json.net设置为基于JSON DeviceConfig属性中的$type类型反序列化为正确的JsonConverter类型{ {3}}或使用与like this

类似的自定义{{1}}