我如何使用BinaryWriter写一个列表
本文关键字:一个 列表 何使用 BinaryWriter | 更新日期: 2023-09-27 18:03:02
我想使用一个通用的WriteList(列表值)函数来写一个使用BinaryWriter的列表。下面是我使用的代码:
public void WriteList<T>(List<T> value)
{
for (int i = 0; i < value.Count; i++)
{
_writer.Write(value[i]);
}
}
我收到的错误是:
Error 1 The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'T' to 'bool'
BinaryFormatter绝对不是一个选项。
我真的不认为你可以避免BinaryFormatter。因为类型T可以是任何复杂类型,并且T的每个实例可以表示内存中的一个巨大的变量图。
所以唯一的解决方案就是将T的实例转换为byte[]格式最简单的解决方案是:BinaryFormatter
实际上,write()方法只接受基本类型的原因是它知道如何将它们直接转换为byte[](使用convert . toxxx()),但对于泛型t,它无法猜测。
作为一种变通方法,你可以这样定义一个接口:public interface IBinarySerializable
{
byte[] GetBytes();
}
,然后在你的类中实现它:
public class MyClass: IBinarySerializable
{
public int X {get;set;}
public byte[] GetBytes()
{
return BitConverter.GetBytes(X); // and anyother
}
}
并将方法更改为:
public void WriteList<T>(List<T> value) where T:IBinarySerializable
{
for (int i = 0; i < value.Count; i++)
{
_writer.Write(value[i].GetBytes());
}
}
如果你检查一下BinaryWriter的文档,你会发现它不接受对象的参数(写基本类型),编译器在过载时尽了最大的努力,但失败了,因为你不能将T转换为bool,或者BinarwWriter想要的任何东西。
你需要把你的对象转换成BinaryWriter可以使用的东西
不能将泛型T传递给BinaryWriter。Write -它对许多特定类型(bool, byte, byte[], int, string等)都有重载,但没有泛型重载。所以你需要自己做,类似于下面的代码。
public void WriteList<T>(List<T> value)
{
for (int i = 0; i < value.Count; i++)
{
switch (Type.GetTypeCode(typeof(T))){
//_writer.Write(value[i]);
case TypeCode.Boolean:
_writer.Write((bool)(object)value[i]);
break;
case TypeCode.Byte:
_writer.Write((byte)(object)value[i]);
break;
case TypeCode.Char:
_writer.Write((char)(object)value[i]);
break;
case TypeCode.Decimal:
_writer.Write((decimal)(object)value[i]);
break;
case TypeCode.Double:
_writer.Write((double)(object)value[i]);
break;
case TypeCode.Single:
_writer.Write((float)(object)value[i]);
break;
case TypeCode.Int16:
_writer.Write((short)(object)value[i]);
break;
case TypeCode.Int32:
_writer.Write((int)(object)value[i]);
break;
case TypeCode.Int64:
_writer.Write((short)(object)value[i]);
break;
case TypeCode.String:
_writer.Write((string)(object)value[i]);
break;
case TypeCode.SByte:
_writer.Write((sbyte)(object)value[i]);
break;
case TypeCode.UInt16:
_writer.Write((ushort)(object)value[i]);
break;
case TypeCode.UInt32:
_writer.Write((uint)(object)value[i]);
break;
case TypeCode.UInt64:
_writer.Write((ulong)(object)value[i]);
break;
default:
if (typeof(T) == typeof(byte[]))
{
_writer.Write((byte[])(object)value[i]);
}
else if (typeof(T) == typeof(char[]))
{
_writer.Write((char[])(object)value[i]);
}
else
{
throw new ArgumentException("List type not supported");
}
break;
}
}