1

バイナリ リーダーを介してファイルから float または double 値を読み取るテンプレート メソッドを作成しようとしています。

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();


   }
}
4

2 に答える 2

2

いつものように、一部の人 (私) は特定の楽器に執着したままです... 持っているものがハンマーしかない場合、すべての問題は釘のように思えます...投稿の履歴で)。ジェネリック型 T に基づいて "適切な" メソッドへのデリゲートをキャッシュする 1 つのクラス。すべてを拡張メソッドとして機能させる別のクラス。

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>();
}
于 2013-08-17T05:45:56.020 に答える
1

これは、ジェネリックが適切な設計選択となるような状況ではありません。

double の配列を受け取る関数と float の配列を受け取る関数の 2 つの関数を作成する方がはるかに優れています。コンパイラは、渡す配列に応じて正しいオーバーロードを選択し、すべてのエラー処理 (int の配列を渡すとどうなるか) とキャストをスローした後、ジェネリック バージョンよりも少ないコードになることさえあります。

于 2013-08-17T04:01:26.167 に答える