2011-07-20 24 views
5

BinaryWriter kullanarak bir liste yazmak için genel bir WriteList (Liste değeri) işlevi kullanmak istiyorum.BinaryWriter kullanarak nasıl bir liste yazarım?

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

ben alıyorum hatadır:

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 kesinlikle değil bir seçenektir İşte kullanıyorum kodudur. Eğer bunu nesnenin bir argüman kabul doesnt göreceksiniz BinaryWriter için dokümanlar kontrol ederse

+3

T üzerinde herhangi bir kısıtlama var mı? T: struct gibi mi? –

cevap

4

(ilkel türleri yazar) ve derleyici beri bunu yapamazsınız, bir aşırı yük de, en iyi çalışıyor ve başarısız olup T'yi bool'a ya da BinarwWriter'in istediği başka bir şeye dönüştürün.

Nesnenizi BinaryWriter ile çalışacak bir şeye dönüştürmek zorunda kalacaksınız.

+0

Örneğin, sınıfın tüm değer türündeki üyelerini almak için yansıma kullanmak ve sonra bunları BinaryWriter ile birbiri ardına yazmak. Bunun cevabınızın bir parçası olduğunu düşünüyorum, çünkü onunla birlikte gidebileceğiniz tek yer hakkında. – hoodaticus

+0

Evet, ama kim isterdi. üye olarak referans türüne sahip bir değer türüne (struct) sahipseniz, sorunlara da girebilirsiniz. Eğer gerçekten bir şey yapmak istediyseniz, bayt [] veya string gibi çıktı almak için özel bir serializer uygulayabilirsiniz. – jasper

+0

Cidden! Bulduğum tek iyi sebep, Silverlight'ta bir BinaryFormatter istemiş olmanızdır. – hoodaticus

5

Gerçekten BinaryFormatter'ı önleyebileceğinizi düşünmüyorum. T türü herhangi bir karmaşık tip olabileceğinden ve T'nin her bir örneği bellekte değişkenlerin büyük bir grafiğini temsil edebilir.

Aslında nedeni gelirse yaz() yöntemi yalnızca ilkel türleri kabul olmasıdır BinaryFormatter

:

nedenle sahip tek çözüm olmasıdır için bayt [] formatında ve en basit çözüm T'nin sizin örneğini dönüştürmek için bunları doğrudan byte [] (Convert.ToXXX() kullanarak) nasıl dönüştüreceğini bilir, ancak jenerik T türünde

bunu tahmin edebilecek hiçbir yol yoktur. Bu şekilde bir arayüz tanımlayabilirsiniz:

ve sonra uygular

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

ve buna yönteminizi değiştirin:: Sınıfınızdaki bunu t

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

Sen BinaryWriter.Write için genel bir T geçemez - birçok spesifik türleri için aşırı yükleme yaparak sahiptir (bool, bayt, bayt [], int, string, vb), ancak genel bir değil. Bu yüzden, aşağıdaki kodla bir şekilde kendiniz yapmalısınız.

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; 
      } 
     } 
İlgili konular