将流反序列化为列表或任何其他类型
尝试将流反序列化为 List
(或任何其他类型),但失败并出现错误:
无法从用法中推断出方法
Foo.Deserialize
的类型参数。尝试显式指定类型参数。(System.IO.Stream)
这失败了:
public static T Deserialize<T>(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return (T)bin.Deserialize(stream);
}
但这可行:
public static List<MyClass.MyStruct> Deserialize(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return (List<MyClass.MyStruct>)bin.Deserialize(stream);
}
或者:
public static object Deserialize(this Stream stream)
{
BinaryFormatter bin = new BinaryFormatter();
return bin.Deserialize(stream);
}
是否可以在不进行强制转换的情况下执行此操作,例如 (List
?
更新:
使用 stream.Deserialize
会导致错误:>()
System.InvalidCastException:无法转换“System.RuntimeType”类型的对象 输入“System.Collections.Generic.List`1[MyClass+MyStruct]”。 在 StreamExtensions.Deserialize[T](Stream 流) 在 MyClass.RunSnippet()
更新 2(示例控制台应用) - 运行一次以创建文件,再次运行以从中读取
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设您像这样调用扩展方法:
在这种情况下,编译器无法确定
Deserialize
的T
(它不会查看方法调用的变量)结果被分配给)。因此,您需要显式指定类型参数:
这有效:
I assume you're calling your extension method like this:
In this case, the compiler cannot determine the
T
forDeserialize
(it doesn't look at the variable the method call result is assigned to).So you need to specify the type argument explicitly:
This works:
您可以使用原始的泛型方法,只需明确指定泛型类型,如下所示......
You can use your original generic method, you just have to specify the generic type explicitly like so...
您正在序列化列表的类型,而不是实际的列表。它应该是:
另外,您必须将
MyStruct
标记为Serializable
才能正确序列化。You are serializing the Type of the list and not the actual list. It should be:
Also, you will have to mark
MyStruct
asSerializable
for it to serialize it correctly.