便携式类库:推荐替代[Serializable]

时间:2012-10-15 20:13:22

标签: c# serialization datacontract serializable portable-class-library

我正在将.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; }

        ...
    }

3 个答案:

答案 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和   哈希表

     

标有Seri​​alizable属性的类型,包括那些   实现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。