[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等。
有什么想法要实现吗?
答案 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(); }
}
}
}
}