我正在将.NET Framework C#类库移植到可移植类库中。一个反复出现的问题是如何处理用[Serializable]
属性修饰的类,因为此属性不是可移植类库子集的一部分。可移植类库子集中的序列化功能似乎由DataContractAttribute涵盖。
[Serializable]
属性替换[DataContract]
就足够了(暗示所有需要序列化的字段和属性都需要用[DataMember]
装饰? [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; }
...
}
答案 0 :(得分:43)
移动类库(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中
System.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 中找到解决方案。
基本上他们正在使用自定义属性提供程序
的方法//不要使用Serializable
#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
[Serializable]
#endif
//使用自定义提供程序
#if NETFX_CORE || PORTABLE
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
#endif
如果项目 PORTABLE
#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]支持?
您可以执行可序列化支持的所有操作,但不包括 在设置名称和顺序之外控制对象的序列化方式。
使用DataContractSerializer有几个好处:
序列化用[DataMember]
修饰的任何内容,即使它不是公开可见的
无法序列化任何内容
您可以使用[Order=]
[DataMember]
属性定义元素序列化的顺序
不需要无参数化构造函数来进行反序列化
比XmlSerializer快10%。
在此处阅读更多内容:XmlSerializer vs DataContractSerializer
也供参考:
DataContract
支持在默认模式下对以下类型的序列化:
CLR内置类型
字节数组,DateTime,TimeSpan,GUID,Uri,XmlQualifiedName, XmlElement和XmlNode数组
枚举
标有DataContract或CollectionDataContract属性的类型
实现IXmlSerializable的类型
数组和集合类,包括List,Dictionary和 哈希表
标有Serializable属性的类型,包括那些 实现ISerializable
没有上述属性(POCO)但具有默认值的类型 构造
答案 1 :(得分:10)
你可以采取一些措施来消除常量预处理程序指令导致的混乱,即将其推送到一个新的SerializableAttribute
类,并基本上欺骗编译器。
#if PORTABLE
namespace System
{
public class SerializableAttribute : Attribute
{
//this does nothing
}
}
#endif
然后继续正常使用Serializable
来装饰你的课程......
答案 2 :(得分:2)
对于.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。