2013-08-17 55 views
0

我試圖創建一個從通過二進制讀取文件讀取float或double值的模板方法。可以bitconverter轉換成字節模板類型「T」?

我不能使用BinaryReader.readSingle或BinaryReader.readDouble方法,因爲它們太具體...可能是讀取字節並使用bitConverter轉換爲float或double。但是,bitConverter可以將字節轉換爲模板類型「T」嗎?

// Note: T type will be either float or double 
static void readValues<T>(string fileName, T[] arr, int arrLen) 
{ 
    BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)); 

    for(int i = 0; i < arrLen; i++) 
    { 
     // Have to use one of the methods to read the values 
     // which one to use 

     // 1. To read float 
     //arr[i] = reader.readSingle(); 

     // 2. To read Double 
     //arr[i] = reader.readDouble(); 


    } 
} 
+0

這將是有益的,如果你要解釋一下什麼是數據的文件格式是(例如如何的值寫入文件,以及以何種格式) – Alex

回答

1

這不是一個很好的情況下,泛型將是一個很好的設計選擇。

你會好得多寫兩個功能,即需要在雙打和一個發生在float數組的數組。編譯器將根據你傳入的數組選擇正確的重載,並且在拋出所有錯誤處理(如果我傳入一個int數組?)並且拋出泛型版本後,它甚至可能最終導致代碼變少。

2

一如往常有些人(我)保持在一定的儀器迷戀...如果你只有一把錘子,你所有的問題會顯得像釘子......如果不使用表達式樹(如果有人有興趣,其他的版本與表達樹是在該職位的歷史)。一個類將一個委託緩存到基於泛型類型T的「right」方法。另一個類使所有工作都成爲擴展方法。

public static class BinaryReaderEx 
{ 
    public static T Read<T>(this BinaryReader br) 
    { 
     return BinaryReader<T>.Read(br); 
    } 
} 

public static class BinaryReader<T> 
{ 
    public static readonly Func<BinaryReader, T> Read; 

    static BinaryReader() 
    { 
     Type type = typeof(T); 

     if (type == typeof(bool)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, bool>)(p => p.ReadBoolean())); 
     } 
     else if (type == typeof(char)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, char>)(p => p.ReadChar())); 
     } 
     else if (type == typeof(string)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, string>)(p => p.ReadString())); 
     } 
     else if (type == typeof(sbyte)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, sbyte>)(p => p.ReadSByte())); 
     } 
     else if (type == typeof(short)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, short>)(p => p.ReadInt16())); 
     } 
     else if (type == typeof(int)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, int>)(p => p.ReadInt32())); 
     } 
     else if (type == typeof(long)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, long>)(p => p.ReadInt64())); 
     } 
     else if (type == typeof(byte)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, byte>)(p => p.ReadByte())); 
     } 
     else if (type == typeof(ushort)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, ushort>)(p => p.ReadUInt16())); 
     } 
     else if (type == typeof(uint)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, uint>)(p => p.ReadUInt32())); 
     } 
     else if (type == typeof(ulong)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, ulong>)(p => p.ReadUInt64())); 
     } 
     else if (type == typeof(float)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, float>)(p => p.ReadSingle())); 
     } 
     else if (type == typeof(double)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, double>)(p => p.ReadDouble())); 
     } 
     else if (type == typeof(decimal)) 
     { 
      Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, decimal>)(p => p.ReadDecimal())); 
     } 
     else 
     { 
      throw new ArgumentException(); 
     } 
    } 
} 

用途:

using (var br = new BinaryReader(ms)) 
{ 
    //byte b = BinaryReader<bool>.Read(br); 
    //double d = BinaryReader<double>.Read(br); 
    //string s = BinaryReader<string>.Read(br); 

    // Or 

    byte b = br.Read<bool>(); 
    double d = br.Read<double>(); 
    string s = br.Read<string>(); 
}