gpt4 book ai didi

c# - 如果调用的类包含 [OnDeserialized] 方法,则在 .NET 应用程序中使用 PCL 时出现 TypeLoadException

转载 作者:可可西里 更新时间:2023-11-01 08:27:28 26 4
gpt4 key购买 nike

我正在将现有的 .NET 类库改编为可移植类库。我正在使用配置文件 78(.NET 4.5、Windows Store 8、Windows Phone 8)而不是配置文件 158(它也针对 Silverlight 5),因为我希望能够编译 unsafe 代码原始库。

.NET 库包含很多标记为 [Serializable] 的类,因此我实现了一个包含虚拟 SerializableAttribute 实现的支持 PCL 库:

public class SerializableAttribute : Attribute { }

这是从主 PCL 库中引用的。

为了在 .NET 应用程序中充分使用主 PCL 库,同时避免类型名称冲突,我还准备了一个 .NET 支持库(与 PCL 支持库具有相同的 strong 名称),其中包含类型转发声明:

[assembly: TypeForwardedTo(SerializableAttribute)]

并且在我的 .NET 应用程序中明确引用 .NET 支持库而不是 PCL 库。

在准备好所有这些并能够成功编译 PCL 适配库后,我重新使用原始 .NET 库中的单元测试,现在引用 PCL 主库和 < em>.NET 支持库。

这通常工作得很好,但对于包含 [Serializable] 类和 [OnDeserialized] 装饰方法的单元测试:

[Serializable]
public class Foo
{
[OnDeserialized]
private void DoSomething(StreamingContext context) { }
}

我得到以下 TypeLoadException:

Type 'Foo' in assembly 'MyPclAssembly' has method 'DoSomething' with an incorrect signature for the serialization attribute that it is decorated with.

(可以注意到 OnDeserializedAttribute 包含在可移植子集中,大概是因为它也在 [DataContract] 序列化中被识别。 )

在原始 .NET 库上运行单元测试时,我没有获得异常。我仔分割析了 Foo 类中的方法签名,它完全符合这些(反)序列化辅助方法应该具有的签名,参见例如here .我还尝试将 [OnDeserialized] 方法的可见性更改为 internalpublic,但无济于事。

使用PCL库时出现这个异常的原因是什么,如何避免?


编辑 我检查了 PCL 库的 IL 代码和 .NET 库的 [OnDeserialized] 方法,我看不出任何相关的区别:

PCL

.method private hidebysig instance void DoSomething(valuetype [System.Runtime.Serialization.Primitives]System.Runtime.Serialization.StreamingContext context) cil managed

.NET

.method private hidebysig instance void  DoSomething(valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed

StreamingContext 的程序集引用不同,但我假设 PCL System.Runtime.Serialization.Primitives 程序集只是一个到 mscorlib 的类型转发程序集 类型?

现在,我决定从我的 PCL 项目中排除 [OnDeserialized] 方法,因为我无论如何都不打算使用序列化。不过,仍然欢迎回答我为什么遇到 TypeLoadException

最佳答案

是的,这是一场你赢不了的游戏。在前面,[Serializable] 属性只与 BinaryFormatter 类相关,该类实现二进制序列化。该类在驻留在手机或平板电脑上的 .NET Framework 版本中可用,因此没有必要尝试让它工作。

您正在与 .NET 中的类型标识 概念作斗争。其中指出类型不仅由命名空间和类型名称标识,而且还由它来自的程序集标识。这是一种非常强大的反 DLL hell 对策,您在这里通过使用在目标体系结构上不可用的类型来避开这种对策。

冷酷的事实是,在 4.5 PCL 库中,StreamingContext 类型存在于 System.Runtime.Serialization.dll 程序集中。针对桌面的应用程序将使用来自 mscorlib.dll 的应用程序。它不是转发类型,它是重复的。 System.Runtime.Serialization.dll 程序集是一个小型填充程序集,其明确目的是隔离这些依赖项并防止 DLL Hell。

Kaboom 在运行时,它发现一个方法的参数类型标识错误。

关于c# - 如果调用的类包含 [OnDeserialized] 方法,则在 .NET 应用程序中使用 PCL 时出现 TypeLoadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20666731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com