繁体   English   中英

如何使用 BinaryWriter 编写列表?

[英]How do I write a list using BinaryWriter?

我想使用一个通用的 WriteList(List value) function 来使用 BinaryWriter 编写一个 List。 这是我正在使用的代码:

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 的每个实例都可以表示 memory 上的巨大变量图。

所以你唯一的解决方案是将你的 T 实例转换为 byte[] 格式,最简单的解决方案是:BinaryFormatter

实际上,原因.Write() 方法只接受原始类型是它知道如何将它们直接转换为 byte[](使用 Convert.ToXXX()),但它无法猜测泛型类型 T。

作为一种解决方法,您可以定义这样的接口:

public interface IBinarySerializable
{
    byte[] GetBytes();
}

然后在您的 class 中实现它:

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的文档,您会发现它不接受 object 的参数(写入原始类型),并且编译器正在尽力解决重载问题,并且失败了,因为您不能将 T 转换为 bool,或 BinarwWriter 想要的任何其他内容。

您将不得不将您的 object 转换为 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;
            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM