2016-10-04 6 views
0

私のアプリケーションはJSONをディスクから読み込み、JSON.netを使ってデシリアライズします。それはうまく動作しています。私のJSONは、このようにレイアウトされてジェネリックリストのインターフェイスから派生したオブジェクトを返す

: "driverTransport" 値に基づいて

{ 
    "driver": { 
    "driverTag": "blah_blah", 
    "driverName": "Blah Blah",   
    "driverTransport": "serial-device" 
    }, 
    "devices": [ 
    { 
     "deviceName": "Dev1", 
     "deviceTag": "DEV1", 
     "deviceStartMode": "Auto"   
    }, 
    { 
     "deviceName": "Dev2", 
     "deviceTag": "DEV2", 
     "deviceStartMode": "Auto"   
    } 
    ] 
} 

、私はどちらかSerialDriverConfig、TelnetDriverConfig、SNMPDriverConfig ...などのクラスにdeserialise。

「ドライバー」プロパティーはすべてのドライバーで同じで、トランスポート・タイプに関係なく、「DriverConfigTemplate」クラスがあります。 「デバイス」はJSONファイルと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; } 
} 

。問題の部分。私がdeserialisingしているとき、私は手の前にトランスポートのタイプをチェックし、使用するクラスを決定します。つまり、シリアルドライバのための私は、「SerialDeviceConfig」を使用して「SerialDriverConfig」クラスとdeserialiseを使用します。

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」機能に渡さを持っています。これは私が数日のために、この1に貼り付けられている

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 (キャストがありませんか?) "このエラーがなぜ発生しているのか理解できますが、回避することはできません。

私のコードは意味があり、誰かが私を助けてくれることを願っています。 ?

+0

DriverConfigTemplateとIDeviceConfigはどのように定義されていますか? インターフェイスが(インターフェイスとインターフェイスが異なる場合)、ベースタイプを返すことはできません。派生型を直接返す必要があります。 –

答えて

1

のために働くなら、私に教えてくださいJSON like this$type属性を持つか、this

と同様のカスタム JsonConverterを使用して、Json.netが正しい DeviceConfigタイプに逆シリアル化するように設定できます
+0

このトリックを行ったJsonConverterを使用して終了しました。みんなからの助けを感謝します。 –

1

このソリューションがあなたのニーズに合っているかどうかはわかりませんが、ジェネリックタイプTを使用してメソッドとSerialDriverConfigを作成した場合、yo urインタフェースを返す型として返します。以下のコードを試すことができますか?

あなたの方法:

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を削除するか、現在の状況に合わせて変更することができます。

・ホープこのことができます、あなたが非ジェネリック

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

、代わりに派生クラス(SerialDriverConfigなど)を使用したのであるためにあなたのDriverConfigクラスを変更することができ、これはあなた

関連する問題