Désérialiser les Flux de Liste<T> ou tout autre type
Tenter de désérialiser un flux de List<T>
(ou tout autre type), et j'échoue avec l'erreur:
Le type des arguments de la méthode
Foo.Deserialize<T>(System.IO.Stream)
ne peut être déduit à partir de l'utilisation. Essayez de spécifier le type des arguments explicitement.
D'échec:
public static T Deserialize<T>(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return (T)bin.Deserialize(stream);
}
Mais cela fonctionne:
public static List<MyClass.MyStruct> Deserialize(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return (List<MyClass.MyStruct>)bin.Deserialize(stream);
}
ou:
public static object Deserialize(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return bin.Deserialize(stream);
}
Est-il possible de le faire sans de la coulée, par exemple (List<MyStruct>)stream.Deserialize()
?
Mise à jour:
À l'aide de stream.Deserialize<List<MyClass.MyStruct>>()
conduit à une erreur:
System.InvalidCastException: Unable to cast object of type 'System.RuntimeType' to type 'System.Collections.Generic.List`1[MyClass+MyStruct]'. at StreamExtensions.Deserialize[T](Stream stream) at MyClass.RunSnippet()
Mise à jour 2 (échantillon console app) - exécuter une fois pour créer le fichier, nouveau de lire
using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
public static class StreamExtensions
{
public static Stream Serialize<T>(this T o) where T : new()
{
Stream stream = new MemoryStream();
BinaryFormatter bin = new BinaryFormatter();
bin.Serialize(stream, typeof(T));
return stream;
}
public static T Deserialize<T>(this Stream stream) where T : new()
{
BinaryFormatter bin = new BinaryFormatter();
return (T)bin.Deserialize(stream);
}
public static void WriteTo(this Stream source, Stream destination)
{
byte[] buffer = new byte[32768];
source.Position = 0;
if(source.Length < buffer.Length) buffer = new byte[source.Length];
int read = 0;
while ((read = source.Read(buffer, 0, buffer.Length)) != 0)
{
destination.Write(buffer, 0, read);
}
}
}
public class MyClass
{
public struct MyStruct
{
public string StringData;
public MyStruct(string stringData)
{
this.StringData = stringData;
}
}
public static void Main()
{
//binary serialization
string filename_bin = "mydata.bin";
List<MyStruct> l;
if(!File.Exists(filename_bin))
{
Console.WriteLine("Serializing to disk");
l = new List<MyStruct>();
l.Add(new MyStruct("Hello"));
l.Add(new MyStruct("Goodbye"));
using (Stream stream = File.Open(filename_bin, FileMode.Create))
{
Stream s = l.Serialize();
s.WriteTo(stream);
}
}
else
{
Console.WriteLine("Deserializing from disk");
try
{
using (Stream stream = File.Open(filename_bin, FileMode.Open))
{
l = stream.Deserialize<List<MyStruct>>();
}
}
catch(Exception ex)
{
l = new List<MyStruct>();
Console.WriteLine(ex.ToString());
}
}
foreach(MyStruct s in l)
{
Console.WriteLine(
string.Format("StringData: {0}",
s.StringData
)
);
}
Console.ReadLine();
}
}
OriginalL'auteur SamWM | 2010-06-01
Vous devez vous connecter pour publier un commentaire.
Je suppose que vous appelez votre méthode d'extension comme ceci:
Dans ce cas, le compilateur ne peut pas déterminer la
T
pourDeserialize
(il ne regarde pas à la variable de l'appel de méthode résultat est attribué à).Vous devez spécifier le type de l'argument explicite:
Cela fonctionne:
typeof(T)
(qui est un RuntimeType) au lieu de l'objeto
!A [Serializable], juste oublié de le mettre dans l'échantillon... bug a été la sérialisation plutôt que de la désérialisation (ne pensez pas que parce qu'il n'y a aucune exception n'est levée)
J'ai eu exactement le même problème avec mon BinaryFormatter, merci pour elle. Il est facile d'oublier depuis XmlSerializer utilise typeof() dans le constructeur.
wow, @dtb ... j'ai eu la même erreur, et j'ai travaillé à travers elle depuis 3 heures jusqu'à ce que j'ai finalement lu vos commentaires et à trouver ma réponse !!
OriginalL'auteur dtb
Vous pouvez utiliser votre générique original de la méthode, il vous suffit de spécifier le type générique explicitement comme si...
OriginalL'auteur Jason Punyon
Vous êtes de la sérialisation du Type de la liste et de ne pas la liste. Il doit être:
Aussi, vous marquez
MyStruct
commeSerializable
pour sérialiser correctement.OriginalL'auteur Adam Hughes