And*_*son 12 c# serialization attributes forward-declaration portable-class-library
我正在将现有的.NET类库改编为可移植类库.我使用配置文件78(.NET 4.5,Windows Store 8,Windows Phone 8)支持配置文件158(也针对Silverlight 5),因为我希望能够编译unsafe原始库的代码.
.NET库包含很多标记的类[Serializable],所以我实现了一个包含虚拟SerializableAttribute实现的支持PCL库:
public class SerializableAttribute : Attribute { }
Run Code Online (Sandbox Code Playgroud)
它是从主PCL库中引用的.
为了充分利用.NET应用程序中的主PCL库,同时避免类型名称冲突,我还准备了一个.NET支持库(具有与PCL支持库相同的强名称),包含类型转发声明:
[assembly: TypeForwardedTo(SerializableAttribute)]
Run Code Online (Sandbox Code Playgroud)
并在我的.NET应用程序中显式引用.NET支持库而不是PCL库.
在准备好所有这些并能够成功编译PCL适配库之后,我将重新使用原始.NET库中的单元测试,现在引用PCL主库和.NET支持库.
这通常非常有效,但对于包含[Serializable]带有[OnDeserialized]装饰方法的类的单元测试:
[Serializable]
public class Foo
{
[OnDeserialized]
private void DoSomething(StreamingContext context) { }
}
Run Code Online (Sandbox Code Playgroud)
我得到以下内容TypeLoadException:
在程序集"MyPclAssembly"中键入"Foo"的方法为"DoSomething",其序列化属性的签名不正确.
(可以注意到,OnDeserializedAttribute 它包含在便携式子集中,可能是因为它在[DataContract]序列化中也被识别出来.)
在原始.NET库上运行单元测试时,我没有获得异常.我仔细分析了Foo类中的方法签名,它完全符合这些(de-)序列化辅助方法应具有的签名,请参见此处.我也试图改变的可见性[OnDeserialized]方法internal和public,但无济于事.
使用PCL库时出现此异常的原因是什么,我该怎么做才能避免它?
编辑我已经检查了PCL库的IL代码和方法的.NET库,我看不出任何相关的区别:[OnDeserialized]
PCL
.method private hidebysig instance void DoSomething(valuetype [System.Runtime.Serialization.Primitives]System.Runtime.Serialization.StreamingContext context) cil managed
Run Code Online (Sandbox Code Playgroud)
.净
.method private hidebysig instance void DoSomething(valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed
Run Code Online (Sandbox Code Playgroud)
程序集引用StreamingContext是不同的,但我假设PCL System.Runtime.Serialization.Primitives程序集只是mscorlib类型的类型转发程序集?
目前,我已决定[OnDeserialized]从我的PCL项目中排除这些方法,因为我不打算使用序列化.不过,我TypeLoadException仍然欢迎回答我遇到这种情况的原因.
是的,这是一场你无法获胜的比赛.在前面,[Serializable]属性只与BinaryFormatter类相关,后者是实现二进制序列化的类.该类在.NET Framework版本中不可用于电话或平板上,因此尝试使其无效是没有意义的.
您正在与.NET中的类型标识概念作斗争.这表明类型不仅仅由命名空间和类型名称标识,而且还标识了它来自的程序集.这是一个非常强大的反DLL地狱对策,你可以通过使用目标架构上无法使用的类型来避开这种对抗.
而冷酷的事实是,在4.5 PCL库中,该StreamingContext类型存在于System.Runtime.Serialization.dll程序集中.针对桌面的应用程序将使用mscorlib.dll中的应用程序.它不是转发类型,而是重复的.System.Runtime.Serialization.dll程序集是一个小的填充程序集,明确意图隔离这些依赖项并防止DLL Hell.
Kaboom在运行时,它看到一个方法具有错误类型标识的参数.
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |