2014-10-08 72 views
0

我需要將字節數組轉換爲不同的數據類型,例如uint16uint32。下面的類包含一個填充了動作的字典,作爲Dictionary實例中的值。行動是BitConverter.ToUInt16BitConverter.ToUInt32基於字符串調用方法

class DataTypes 
{ 
    private Dictionary<string, Action> _dict; 

    public DataTypes() 
    { 
     // create new dictionary 
     _dict = new Dictionary<string, Action>(); 

     // fill dictionary with key-value pairs 
     _dict.Add("uint16", BitConverter.ToUInt16); 
     _dict.Add("uint32", BitConverter.ToUInt32); 
     _dict.Add("sint16", BitConverter.ToInt16); 
     _dict.Add("sint32", BitConverter.ToInt32); 
    } 

    // converts byte-array to specified type 
    public object getValue(string type, byte[] data, int pos) // e.g. type = "uint16" 
    { 
     if (_dict.ContainsKey(type)) 
      return _dict[type](data, pos); 
     return null; 
    } 
} 

上面的代碼不運行,因爲編譯器需要一個帶'void ToUInt32()'簽名(帶大括號)的方法。

有誰知道我該怎麼做到這一點。

回答

3

您可以使用以下改寫:

private Dictionary<string, Func<byte[], int, object>> _dict; 

    public void DataTypes() 
    { 
     // create new dictionary 
     _dict = new Dictionary<string, Func<byte[], int, object>> 
     { 
      // fill dictionary with key-value pairs 
      {"uint16", (data, pos) => BitConverter.ToUInt16(data, pos)}, 
      {"uint32", (data, pos) => BitConverter.ToUInt32(data, pos)}, 
      {"sint16", (data, pos) => BitConverter.ToInt16(data, pos)}, 
      {"sint32", (data, pos) => BitConverter.ToInt32(data, pos)} 
     }; 
    } 

    // converts byte-array to specified type 
    public object getValue(string type, byte[] data, int pos) // e.g. type = "uint16" 
    { 
     if (_dict.ContainsKey(type)) 
      return _dict[type](data, pos); 
     return null; 
    } 
+0

謝謝!我喜歡這個! – Boozzz 2014-10-08 09:50:34

+0

@Boozzz如果解決方案沒有問題,那麼你應該將它標記爲答案 – 2014-10-08 10:57:11

2

Agumenting Ivan Zub's answer:你不需要重新字典每次實例化類的時候,你可以把字典中的靜態字段。

public class DataTypes 
{ 
    private static readonly IReadOnlyDictionary<string, Func<IEnumerable<byte>, int, object>> Converters; 

    static DataTypes() 
    { 
     Converters = 
      new ReadOnlyDictionary<string, Func<IEnumerable<byte>, int, object>>(
       new Dictionary<string, Func<IEnumerable<byte>, int, object>> 
       { 
        { "System.UInt16", (value, startIndex) => BitConverter.ToUInt16(value.ToArray(), startIndex) }, 
        { "System.UInt32", (value, startIndex) => BitConverter.ToUInt32(value.ToArray(), startIndex) }, 
        { "System.Int16", (value, startIndex) => BitConverter.ToInt16(value.ToArray(), startIndex) }, 
        { "System.Int32", (value, startIndex) => BitConverter.ToInt32(value.ToArray(), startIndex) } 
       }); 
    } 

    public object GetValue(string type, byte[] value, int startIndex) 
    { 
     if (!Converters.ContainsKey(type)) 
     { 
      throw new ArgumentOutOfRangeException("type"); 
     } 

     return Converters[type](value, startIndex); 
    } 
} 

如果該類沒有其他方法(或不依賴於內部狀態),就可以使雙方的等級和GetValue靜態了。

+0

當參數'type =「uint16時,這在最後一行代碼行('Converters [type](value,startIndex);')中通過'ArgumentOutOfRangeException' 「','value'是'byte [80]'和'startIndex = 50'。 – Boozzz 2014-10-08 10:14:13

+0

檢查你的調試器,你確定它不是'拋出新的ArgumentOutOfRangeException(「type」);'誰在拋出?請注意,我正在使用[完全限定名稱](http://msdn.microsoft.com/zh-cn/library/dfb3cx8s(v = vs.71).aspx)作爲字典密鑰。 – Albireo 2014-10-08 10:17:25

+0

是的,當然。謝謝!!! – Boozzz 2014-10-08 10:20:04