C# 可移植类库:推荐替换 [Serializable]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12903262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Portable class library: recommended replacement for [Serializable]
提问by Anders Gustafsson
I am porting a .NET Framework C# class library to a Portable Class Library. One recurring problem is how to deal with classes decorated with the [Serializable]attribute, since this attribute is not part of the Portable Class Library subset. Serialization functionality in the Portable Class Library subset instead appears to be covered by DataContractAttribute.
我正在将 .NET Framework C# 类库移植到可移植类库。一个反复出现的问题是如何处理用该[Serializable]属性修饰的类,因为该属性不是可移植类库子集的一部分。可移植类库子集中的序列化功能似乎由DataContractAttribute覆盖。
- To preserve as much of functionality as possible in the Portable Class Library, is it sufficient to replace
[Serializable]with the[DataContract]attribute (with the implication that all fields and properties subject to serialization would need to be decorated with[DataMember]as well)? - What (if anything) will I notbe able to do with this approach that I cando with
[Serializable]applied? - Is there a less intrusive approach?
- 为了尽可能多地保留可移植类库中的功能,是否
[Serializable]用[DataContract]属性替换就足够了(暗示所有受序列化约束的字段和属性也需要装饰[DataMember])? - (如果有的话)将我什么不能够使用这种方法,我做的可以用做
[Serializable]应用? - 有没有一种侵入性较小的方法?
Given that [DataContract]and [DataMember]are used, I am considering to change the code along the following lines. Are there any obvious flaws with this approach? Is there any way to formulate the same thing less verbose?
鉴于此[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; }
...
}
采纳答案by Matija Grcic
Portable Class Libraries (PCLs) now officially deprecated[16 August 2017]
便携式类库 (PCL) 现已正式弃用[2017 年 8 月 16 日]
If you're sharing code between different .NET implementations today, you're probably aware of Portable Class Libraries (PCLs). With the release of .NET Standard 2.0, we're now officially deprecating PCLs and you should move your projects to .NET Standard.
如果您今天在不同的 .NET 实现之间共享代码,您可能知道可移植类库 (PCL)。随着 .NET Standard 2.0 的发布,我们现在正式弃用 PCL,您应该将您的项目移至 .NET Standard。
Source:Announcing .NET Standard 2.0
Portable Class Library (PCL) now available on all platforms [14 Oct 2013]
便携式类库 (PCL) 现在可在所有平台上使用 [2013 年 10 月 14 日]
Prior to today's release, there was a license restriction with the PCL reference assemblies which meant they could only be used on Windows. With today's release we are announcing a new standalone release of the PCL reference assemblies with a license that allows it to be used on any platform – including non-Microsoft ones.This enables developers even more flexibility and to do great things with .NET.
在今天发布之前,PCL 参考程序集存在许可限制,这意味着它们只能在 Windows 上使用。在今天的发布中,我们宣布了 PCL 参考程序集的新独立版本,其许可允许在任何平台上使用,包括非 Microsoft 平台。这使开发人员能够更加灵活地使用 .NET 做伟大的事情。
Source:Portable Class Library (PCL) now available on all platforms
Download:Microsoft .NET Portable Library Reference Assemblies 4.6 RC
下载:Microsoft .NET Portable Library Reference Assemblies 4.6 RC
Just for the reference the allowed set of assemblies are:
仅供参考,允许的程序集集是:
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 (from Silverlight)
mscorlib.dll
系统文件
系统核心文件
系统文件
System.ComponentModel.Composition.dll (MEF)
系统.Net.dll
系统.运行时.序列化.dll
系统服务模型.dll
系统.Xml.Serialization.dll
System.Windows.dll(来自 Silverlight)
As far as I know you need to mark the fields with DataMemberattribute, and add the DataContractattribute.
据我所知,您需要使用DataMember属性标记字段,并添加DataContract属性。
UPDATE
更新
Yes.
是的。
You can look how Json.NETportable class library solution is implemented. You can find the solution in the Source\Src\Newtonsoft.Json.Portablewhen you download the project from here Json.NET 4.5 Release 10 (source + binary).
您可以查看Json.NET可移植类库解决方案是如何实现的。当您从这里Json.NET 4.5 Release 10 (source + binary)下载项目时,您可以在Source\Src\Newtonsoft.Json.Portable 中找到解决方案。
Basically they are using an approach with a custom attribute provider
基本上,他们使用的是自定义属性提供程序的方法
//don't use Serializable
//不要使用可序列化
#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
[Serializable]
#endif
//use custom provider
//使用自定义提供者
#if NETFX_CORE || PORTABLE
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
#endif
And if project is PORTABLE
如果项目是便携式的
#if !PocketPC && !NET20
DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
if (dataContractAttribute != null)
return MemberSerialization.OptIn;
#endif
where OptIndescription is:
其中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,
Hope it helps.
希望能帮助到你。
UPDATE 2
更新 2
Am I losing any abilities using [DataContract] instead of [Serializable], or will I still be able to do everything that [Serializable] supports?
我是否会使用 [DataContract] 而不是 [Serializable] 失去任何能力,或者我仍然能够执行 [Serializable] 支持的所有操作?
You can do everything that Serializablesupports except control over how the object is serialized outside of setting the name and the order.
您可以执行Serializable支持的所有操作,除了在设置名称和顺序之外控制对象的序列化方式。
Using DataContractSerializerhas several benefits:
使用DataContractSerializer有几个好处:
serialize anything decorated with a [DataMember]even if it's not public visible
序列化任何装饰有 a 的东西,[DataMember]即使它不是公开可见的
can't serialize anything unless you specifically tell it to ("opt-in")
不能序列化任何东西,除非你特别告诉它(“选择加入”)
you can define the order in which the elements are serialized using the [Order=]attribute on the [DataMember]
您可以使用上的[Order=]属性定义元素序列化的顺序[DataMember]
doesn't require a parameterless constructor for deserialization
不需要用于反序列化的无参数构造函数
is 10% faster than XmlSerializer.
比 XmlSerializer 快 10%。
Read more here: XmlSerializer vs DataContractSerializer
在此处阅读更多信息:XmlSerializer 与 DataContractSerializer
Also for the reference:
也供参考:
DataContractsupports serialization of the following kinds of types in the default mode:
CLR built-in types
DataContract默认模式下支持以下几种类型的序列化:CLR 内置类型
Byte array, DateTime, TimeSpan, GUID, Uri, XmlQualifiedName, XmlElement and XmlNode array
Enums
Types marked with DataContract or CollectionDataContract attribute
Types that implement IXmlSerializable
Arrays and Collection classes including List, Dictionary and Hashtable
Types marked with Serializable attribute including those that implement ISerializable
Types with none of the above attributes (POCO) but with a default constructor
字节数组、DateTime、TimeSpan、GUID、Uri、XmlQualifiedName、XmlElement 和 XmlNode 数组
枚举
用 DataContract 或 CollectionDataContract 属性标记的类型
实现 IXmlSerializable 的类型
数组和集合类,包括列表、字典和哈希表
用 Serializable 属性标记的类型,包括实现 ISerializable 的类型
没有上述属性(POCO)但具有默认构造函数的类型
回答by Steve Danner
One thing you could do to eliminate the clutter that the constant preprocessor directives causes is to push that off to one new SerializableAttributeclass and basically trick the compiler.
为了消除常量预处理器指令导致的混乱,您可以做的一件事是将其推送到一个新SerializableAttribute类并基本上欺骗编译器。
#if PORTABLE
namespace System
{
public class SerializableAttribute : Attribute
{
//this does nothing
}
}
#endif
Then just continue to decorate your classes with Serializableas normal...
然后继续Serializable像往常一样装饰你的课程......
回答by Lex
For .Net 4.6 and up the DataContract is no longer available to PCL. You need to add the Nuget package System.Runtime.Serialization.Primitives available here: https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/
对于 .Net 4.6 及更高版本,PCL 不再可以使用 DataContract。您需要在此处添加 Nuget 包 System.Runtime.Serialization.Primitives:https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/
Note for actual serialisation you'll probably also need an implementation such as System.Runtime.Serialization.Json, System.Runtime.Serialization.Xml or a Newtonsoft.Json.
注意对于实际的序列化,您可能还需要一个实现,例如 System.Runtime.Serialization.Json、System.Runtime.Serialization.Xml 或 Newtonsoft.Json。

