C#BinaryFormatter - 如何找出二进制数据的类?

时间:2022-12-19 16:08:03

I want to deserialize an object but don't know the class up front. So, consider the following code...

我想反序列化一个对象,但不知道前面的类。所以,请考虑以下代码......

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject)formatter.Deserialize(stream);

What could I do if I don't know the class up front? Say, for example "MyFile.bin" was a MyObject or a MyFoo. How do I determine which object to instantiate?

如果我不了解课程,我该怎么办?比方说,例如“MyFile.bin”是MyObject或MyFoo。如何确定要实例化的对象?

Something like...

if (magic happens here == typeof(MyObject))  
    MyObject obj = (MyObject) formatter.Deserialize(stream);   
else if (more magic happens here == typeof(MyFoo))  
    MyFoo foo = (MyFoo)formatter.Deserialize(stream);

3 个解决方案

#1


7  

Just do:

object result = formatter.Deserialize(stream); 
Type t = result.GetType();

#2


1  

Mainly as leppie says...

主要是因为leppie说......

If you want to test it for a few known types, you can use "is"/"as":

如果要测试几种已知类型,可以使用“is”/“as”:

MyFoo foo = result As MyFoo;
if(foo != null) { // it was one of those
  // special code
}

But in general, you would let the serializer worry about such details...

但总的来说,你会让串行器担心这些细节......

It is very different with xml-based serializers, of course, since you need to tell the serializer what is expected, rather than the serializer telling you what it got.

当然,它与基于xml的序列化程序非常不同,因为您需要告诉序列化程序预期的内容,而不是序列化程序告诉您它的内容。

#3


0  

A few suggestions,

一些建议,

  1. If you deserialize the object without casting object myObject = formatter.Deserialize(stream); and then use the "as" operator to check for type compatibility to known types then that might work.

    如果在不抛出对象的情况下反序列化对象myObject = formatter.Deserialize(stream);然后使用“as”运算符检查可能有效的已知类型的类型兼容性。

  2. Take a look at BinaryFormatter.Binder property which is of type SerializationBinder, we've used it before to do backward compatibility for older versions of our file format and it worked out great. Basically allows you to totally control what something gets deserialized as.

    看看BinaryFormatter.Binder属性,它是SerializationBinder类型,我们之前使用它来为我们的文件格式的旧版本做后向兼容性并且效果很好。基本上允许你完全控制什么东西被反序列化。

#1


7  

Just do:

object result = formatter.Deserialize(stream); 
Type t = result.GetType();

#2


1  

Mainly as leppie says...

主要是因为leppie说......

If you want to test it for a few known types, you can use "is"/"as":

如果要测试几种已知类型,可以使用“is”/“as”:

MyFoo foo = result As MyFoo;
if(foo != null) { // it was one of those
  // special code
}

But in general, you would let the serializer worry about such details...

但总的来说,你会让串行器担心这些细节......

It is very different with xml-based serializers, of course, since you need to tell the serializer what is expected, rather than the serializer telling you what it got.

当然,它与基于xml的序列化程序非常不同,因为您需要告诉序列化程序预期的内容,而不是序列化程序告诉您它的内容。

#3


0  

A few suggestions,

一些建议,

  1. If you deserialize the object without casting object myObject = formatter.Deserialize(stream); and then use the "as" operator to check for type compatibility to known types then that might work.

    如果在不抛出对象的情况下反序列化对象myObject = formatter.Deserialize(stream);然后使用“as”运算符检查可能有效的已知类型的类型兼容性。

  2. Take a look at BinaryFormatter.Binder property which is of type SerializationBinder, we've used it before to do backward compatibility for older versions of our file format and it worked out great. Basically allows you to totally control what something gets deserialized as.

    看看BinaryFormatter.Binder属性,它是SerializationBinder类型,我们之前使用它来为我们的文件格式的旧版本做后向兼容性并且效果很好。基本上允许你完全控制什么东西被反序列化。