Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从第三方DLL反序列化二进制序列化实例会给出未初始化/空实例_C#_Properties_Deserialization - Fatal编程技术网

C# 从第三方DLL反序列化二进制序列化实例会给出未初始化/空实例

C# 从第三方DLL反序列化二进制序列化实例会给出未初始化/空实例,c#,properties,deserialization,C#,Properties,Deserialization,我有一个包含来自第三方dll的类的二进制序列化实例的文件集合。我没有访问第三方源代码的权限,但我有dll。我需要将这些文件反序列化为类的实例 我只是这样做: Stream stream = File.Open(@"C:\my\path", FileMode.Open); BinaryFormatter binaryFormatter = new BinaryFormatter(); ThirdPartyType o = binaryFormatter.Deserialize(stream) as

我有一个包含来自第三方dll的类的二进制序列化实例的文件集合。我没有访问第三方源代码的权限,但我有dll。我需要将这些文件反序列化为类的实例

我只是这样做:

Stream stream = File.Open(@"C:\my\path", FileMode.Open);
BinaryFormatter binaryFormatter = new BinaryFormatter();
ThirdPartyType o = binaryFormatter.Deserialize(stream) as ThirdPartyType;
stream.Close();
这没有错误。当我在调试模式下运行项目并在反序列化后放置断点时,我可以检查实例o。o的所有成员都为null或0,因此创建了实例,但没有将任何成员初始化为正确的值

我已尝试使用.Net Reflector反编译dll,并在以下位置插入断点:

protected ThirdPartyType(SerializationInfo info, StreamingContext context) {}
现在我可以检查参数信息,在这里我可以看到成员m_类型、m_成员和m_数据被设置为我期望从序列化文件中得到的正确值。但是,由于某些原因,构造函数不会使用它并正确初始化实例。我只能看到这个构造函数头,反编译不会显示它的代码

为了自己控制初始化,我创建了一个类的本地子类:

[Serializable]
public class FakeThirdPartyType : ThirdPartyType
{
    protected FakeThirdPartyType(SerializationInfo info, StreamingContext context) : base(info, context)
    {
        int width = info.GetInt32("clientWidth");
        this.ClientWidth = width;
        //Many other properties as well...
    }
}
然后我将我的BinaryFormatter绑定到SerializationBinder,当要求输入ThirdPartyType时,它会返回FakeThirdPartyType,对于任何其他调用都会返回正确的类型。现在,当我运行反序列化构造函数时,我就可以使用它了。但这里我有一个非常奇怪的问题。我可以看到宽度被分配了正确的值=0,但在下一行之后,this.ClientWidth仍然为0。与以下结果相同:

base.GetType().GetProperty("ClientWidth").SetValue(this, width, null);
我可能做错了什么吗?我遇到的问题是否可能是由交叉程序集反序列化引起的?错误是否可能存在于我无法访问的第三方代码中?属性的setter似乎不起作用,至少不会影响getter返回的变量


在调试期间,我可以检查ThirdPartyType类型,并查看它是否具有私有字段\u clientWidth,但我找不到任何方法直接设置该字段。

反编译后,该类的属性都如下所示:

    public int Property
    {
        [MethodImpl(MethodImplOptions.NoInlining)]
        get
        {
            return 0;
        }
        [MethodImpl(MethodImplOptions.NoInlining)]
        set
        {
        }
    }

    public Object Property2
    {
        [MethodImpl(MethodImplOptions.NoInlining)]
        get
        {
            return null;
        }
    }

这当然会导致反序列化后所有值都为null和0。为什么这些属性是这样的是一个谜。但这不在本问题的范围内。

第三方类型还有哪些其他构造函数?另外,如果属性设置器不使用特殊的设置方法/传递到ctor/从其他属性计算/etc,如何设置其中的值?我还尝试了basenull、context,这不会引发错误,因此我怀疑原始构造函数只是空的,并且原始实现者并不打算对其进行反序列化。非常奇怪,因为他们向我提供了一组序列化对象。@mlorbetske:唯一一个参数是System.Web.UI的对象。Page@mlorbetske当前位置我不知道这些值首先是如何到达那里的。我只有序列化版本,并且在那里它们被正确设置。也许问题出在其他地方,比如我的dll引用中。但我想我有正确的版本。它与序列化文件中的版本匹配。