Как мне написать список, используя BinaryWriter? - PullRequest
5 голосов
/ 21 июля 2011

Я хочу использовать универсальную функцию 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 абсолютно , а не вариант.

Ответы [ 3 ]

6 голосов
/ 21 июля 2011

Я действительно не думаю, что вы можете избежать 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());
    }
}
4 голосов
/ 21 июля 2011

Вы не можете передать универсальный 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;
            }
        }
4 голосов
/ 21 июля 2011

Если вы посмотрите документы для BinaryWriter , вы увидите, что он не принимает аргумент объекта ( Записывает типы примитивов ), а компилятор старается изо всех сил при перегрузкеи потерпел неудачу, так как вы не можете привести свой T к bool или к чему-либо еще, что BinarwWriter захочет.

Вам нужно будет преобразовать ваш объект во что-то, с чем будет работать BinaryWriter.

...