可移植类库:推荐替换 [Serializable]
Posted
技术标签:
【中文标题】可移植类库:推荐替换 [Serializable]【英文标题】:Portable class library: recommended replacement for [Serializable] 【发布时间】:2012-10-05 21:04:04 【问题描述】:我正在将 .NET Framework C# 类库移植到可移植类库。一个反复出现的问题是如何处理用[Serializable]
属性修饰的类,因为该属性不是可移植类库子集的一部分。可移植类库子集中的序列化功能似乎被 DataContractAttribute 覆盖。
[Serializable]
替换为[DataContract]
属性是否足够(这意味着所有要进行序列化的字段和属性都需要用@ 装饰987654325@ 也是)?
我不能用我可以做的这种方法做什么(如果有的话)与[Serializable]
应用?
有没有侵入性较小的方法?
鉴于使用了[DataContract]
和[DataMember]
,我正在考虑按照以下几行更改代码。这种方法有什么明显的缺陷吗?有什么方法可以让同样的事情变得不那么冗长吗?
#if PORTABLE
[DataContract]
#else
[Serializable]
#endif
public class SerializableClass : SerializableBaseClass
...
#if !PORTABLE
protected SerializableClass(SerializationInfo info, StreamingContext context)
: base(info, context)
#endif
...
#if PORTABLE
[DataMember]
#endif
private Type1 _serializableField;
#if PORTABLE
[DataMember]
#endif
private Type2 SerializableProperty get; set;
...
【问题讨论】:
【参考方案1】:便携式类库 (PCL) 现已正式弃用 [2017 年 8 月 16 日]
如果您现在在不同的 .NET 实现之间共享代码, 您可能知道可移植类库 (PCL)。随着 .NET Standard 2.0 发布后,我们现在正式弃用 PCL 并且您应该将您的项目迁移到 .NET Standard。
来源: Announcing .NET Standard 2.0
可移植类库 (PCL) 现已在所有平台上可用 [2013 年 10 月 14 日]
在今天发布之前,PCL 存在许可限制 引用程序集,这意味着它们只能在 Windows 上使用。 随着今天的发布,我们宣布了一个新的独立版本 PCL 参考程序集,其许可证允许在 任何平台 - 包括非 Microsoft 平台。 这使开发人员能够 更大的灵活性并使用 .NET 做伟大的事情。
来源: Portable Class Library (PCL) now available on all platforms
下载: Microsoft .NET Portable Library Reference Assemblies 4.6 RC
仅供参考,允许的程序集是:
mscorlib.dll
系统.dll
System.Core.dll
System.Xml.dll
System.ComponentModel.Composition.dll (MEF)
System.Net.dll
System.Runtime.Serialization.dll
System.ServiceModel.dll
System.Xml.Serialization.dll
System.Windows.dll(来自 Silverlight)
据我所知,您需要用 DataMember 属性标记字段,并添加 DataContract 属性。
更新
是的。
您可以查看Json.NET 可移植类库解决方案是如何实现的。当您从此处Json.NET 4.5 Release 10 (source + binary) 下载项目时,您可以在 Source\Src\Newtonsoft.Json.Portable 中找到解决方案。
基本上他们使用的是自定义属性提供者的方法
//不要使用可序列化
#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
[Serializable]
#endif
//使用自定义提供者
#if NETFX_CORE || PORTABLE
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
#endif
如果项目是便携
#if !PocketPC && !NET20
DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
if (dataContractAttribute != null)
return MemberSerialization.OptIn;
#endif
其中 OptIn 描述为:
/// <summary>
/// Only members must be marked with <see cref="JsonPropertyAttribute"/> or <see cref="DataMemberAttribute"/> are serialized.
/// This member serialization mode can also be set by marking the class with <see cref="DataContractAttribute"/>.
/// </summary>
OptIn,
希望对你有帮助。
更新 2
我是否会失去使用 [DataContract] 而不是的任何能力 [Serializable],或者我仍然可以做任何事情吗? [Serializable] 支持吗?
你可以做所有 Serializable 支持的事情,除了 除了设置名称和顺序之外,还可以控制对象的序列化方式。
使用DataContractSerializer 有几个好处:
序列化任何用[DataMember]
装饰的东西,即使它不公开可见
除非您明确告诉 ("opt-in")
,否则无法序列化任何内容您可以使用[DataMember]
上的[Order=]
属性定义元素的序列化顺序
反序列化不需要无参数构造函数
比 XmlSerializer 快 10%。
在此处阅读更多信息:XmlSerializer vs DataContractSerializer
也供参考:
DataContract
在默认模式下支持以下几种类型的序列化:
CLR 内置类型
字节数组、日期时间、时间跨度、GUID、Uri、XmlQualifiedName、 XmlElement 和 XmlNode 数组
枚举
用 DataContract 或 CollectionDataContract 属性标记的类型
实现 IXmlSerializable 的类型
数组和集合类,包括列表、字典和 哈希表
标有 Serializable 属性的类型,包括那些 实现 ISerializable
没有上述属性(POCO)但具有默认值的类型 构造函数
【讨论】:
我主要关心的是;用 [DataContract] 和 [DataMember] 装饰是否足以替代 [Serializable]? 非常感谢您提供的信息更新,我将仔细研究 JSON。我是否会失去使用 [DataContract] 而不是 [Serializable] 的任何能力,还是我仍然能够做 [Serializable] 支持的所有事情?【参考方案2】:要消除常量预处理器指令导致的混乱,您可以做的一件事是将其推到一个新的SerializableAttribute
类中,基本上欺骗编译器。
#if PORTABLE
namespace System
public class SerializableAttribute : Attribute
//this does nothing
#endif
然后像往常一样继续用Serializable
装饰你的类...
【讨论】:
谢谢!但是,使用此解决方案,序列功能将被忽略,对吧? 这不起作用 - 有一个例外,如“类型 *** 未标记为可序列化。” 使用 Shim NuGet 包解决了第一个问题,但是库存序列化不能很好地与 Azure .NET 后端配合使用(非 clr 类型不会被序列化;只是 null 到达 AMS 端)。所以看起来我在关注 DataContractSerializer 为我工作。SerializableAttribute
在 System
命名空间中很重要【参考方案3】:
对于 .Net 4.6 及更高版本,PCL 不再可以使用 DataContract。您需要在此处添加 Nuget 包 System.Runtime.Serialization.Primitives:https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/
注意,对于实际的序列化,您可能还需要一个实现,例如 System.Runtime.Serialization.Json、System.Runtime.Serialization.Xml 或 Newtonsoft.Json。
【讨论】:
我不知道你能做到这一点!节省了我很多时间,让我的生活更轻松!谢谢!以上是关于可移植类库:推荐替换 [Serializable]的主要内容,如果未能解决你的问题,请参考以下文章