在泛型类中使用BinaryWriter

时间:2018-12-19 14:23:30

标签: c# delegates

[Serializable]
public class Vector3D<T> {
    public T x;
    public T y;
    public T z;
}

我有一个简单的Vector类,用于存储各种数值类型的坐标。

我需要从文件中读取它,然后再存储它。

通常看起来像这样:

someCoord = new Vector3D<int> {
                x = reader.ReadInt32(),
                y = reader.ReadInt32(),
                z = reader.ReadInt32()
            };
writer.Write(someCoord.x);
writer.Write(someCoord.y);
writer.Write(someCoord.z);

我希望将这些行变成这样:

someCoord = new Vector3D<int>(reader);
someCoord.Write(writer);

我将在Vector3D类中准备好Read和Write方法。虽然写作不是问题,因为我可以做类似的事情:

writer.Write((T)x)

尝试以相同的方式读取成为一个问题,因为必须调用不同名称的方法,具体取决于要读取的类型。

说了这么多,是否还有一些聪明的方法可以实现这一目标? 我当时正在考虑使用委托,但我无法弄清楚语法。

我要有一本字典,里面放着Type-Function(委托)对,这样当我想读一些东西时,我会这样称呼:

T value = reader.dictionary[T]();

其中reader是BinaryReader的实例。如果T为int,则将dictionary [T]替换为readInt32,如果T为float,则将Dictionary [T]替换为readSingle等。

有什么想法要实现吗?

1 个答案:

答案 0 :(得分:0)

您可以创建一个依赖于<T>泛型类型的泛型方法,处理读取,将值装箱并最终返回它。例如:

    public static Object GetValue<T>(BinaryReader br) {
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean: { return br.ReadBoolean(); }
            case TypeCode.Byte: { return br.ReadByte(); }
            case TypeCode.Char: { return br.ReadChar(); }
            case TypeCode.Decimal: { return br.ReadDecimal(); }
            case TypeCode.Double: { return br.ReadDouble(); }
            case TypeCode.Int16: { return br.ReadInt16(); }
            case TypeCode.Int32: { return br.ReadInt32(); }
            case TypeCode.Int64: { return br.ReadUInt64(); }
            // Keep on going for other types
            default: { return br.Read(); }
        }
    }

这是一个完整的示例

public class Vector3D<T>
{
    public T X { get; set; }
    public T Y { get; set; }
    public T Z { get; set; }
    private readonly String filePath;
    public Vector3D(String filePath) {
        this.filePath = filePath;
        if (File.Exists(filePath))
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                using(BinaryReader br = new BinaryReader(fs))
                {
                    X = (T) GetValue<T>(br);
                    Y = (T) GetValue<T>(br);
                    Z = (T) GetValue<T>(br);
                }
            }
        }
    }

    public static Object GetValue<T>(BinaryReader br) {
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean: { return br.ReadBoolean(); }
            case TypeCode.Byte: { return br.ReadByte(); }
            case TypeCode.Char: { return br.ReadChar(); }
            case TypeCode.Decimal: { return br.ReadDecimal(); }
            case TypeCode.Double: { return br.ReadDouble(); }
            case TypeCode.Int16: { return br.ReadInt16(); }
            case TypeCode.Int32: { return br.ReadInt32(); }
            case TypeCode.Int64: { return br.ReadUInt64(); }
            default: { return br.Read(); }
        }
    }
}

您还可以为此创建扩展方法:

public static class BinaryReaderExtensions
{
    public static Object GetValue(this BinaryReader br, Type type)
    {
        switch (Type.GetTypeCode(type))
        {
            case TypeCode.Boolean: { return br.ReadBoolean(); }
            case TypeCode.Byte: { return br.ReadByte(); }
            case TypeCode.Char: { return br.ReadChar(); }
            case TypeCode.Decimal: { return br.ReadDecimal(); }
            case TypeCode.Double: { return br.ReadDouble(); }
            case TypeCode.Int16: { return br.ReadInt16(); }
            case TypeCode.Int32: { return br.ReadInt32(); }
            case TypeCode.Int64: { return br.ReadUInt64(); }
            default: { return br.Read(); }
        }
    }
}

}