开发者

How do I write a list using BinaryWriter?

I want to use a generic WriteList(List value) function to write a List using the BinaryWriter. Here is the code I am using:

public void WriteList<T>(List<T> value)
{
    for (int i = 0; i < value.Count; i++)
    {
        _writer.Write(value[i]);
    }
}

The error I am receiving is:

 Error  1   The best overloaded method match for 'System.IO.BinaryWriter.Writ开发者_StackOverflowe(bool)' has some invalid arguments    
Error   2   Argument 1: cannot convert from 'T' to 'bool'   

The BinaryFormatter is absolutely not an option.


I really don't think you can avoid BinaryFormatter. Because type T can be any complex type and each instance of T can represent a huge graph of variables on memory.

so the only solution you have is to convert your instance of T to the byte[] format and the simplest solution for that is: BinaryFormatter

Actually the reason .Write() method only accept primitive types is that it knows how to convert them directly to byte[] (using Convert.ToXXX()) but there is no way it could guess that for generic type T.

As a work around you can define an interface like this:

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

and then implement it in your class:

public class MyClass: IBinarySerializable
{
    public int X {get;set;}
    public byte[] GetBytes()
    {
        return BitConverter.GetBytes(X); // and anyother
    }
}

and change your method to this:

public void WriteList<T>(List<T> value) where T:IBinarySerializable
{
    for (int i = 0; i < value.Count; i++)
    {
        _writer.Write(value[i].GetBytes());
    }
}


If you check out the docs for BinaryWriter you'll see it doesnt accept an argument of object (Writes primitive types), and the compiler is trying its best at an overload, and failing, since you can't cast your T to bool, or anything else that BinarwWriter would like.

You're going to have to convert your object into something the BinaryWriter will work with.


You can't pass a generic T to BinaryWriter.Write - it has overloads for many specific types (bool, byte, byte[], int, string, etc), but no generic one. So you'll need to do it yourself, in some way similar to the code below.

    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;
            }
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜