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

And*_*son 43 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; }

        ...
    }
Run Code Online (Sandbox Code Playgroud)

Mat*_*cic 43

便携式类库(PCL)现已正式弃用 [2017年8月16日]

如果您今天在不同的.NET实现之间共享代码,那么您可能已经了解了可移植类库(PCL).随着.NET Standard 2.0的发布,我们现在正式弃用PCL,您应该将项目转移到.NET Standard.

来源: 宣布.NET Standard 2.0

便携式类库(PCL)现已在所有平台上提供[2013年10月14日]

在今天发布之前,PCL参考组件存在许可限制,这意味着它们只能在Windows上使用.随着今天的发布,我们宣布了一个新的PCL参考组件的独立版本,其许可证允许它在任何平台上使用 - 包括非Microsoft的平台. 这使开发人员能够更灵活地使用.NET做出很棒的事情.

资料来源: 可移植类库(PCL)现已在所有平台上提供

下载: Microsoft .NET可移植库参考组件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属性.

UPDATE

是.

您可以了解如何实现Json.NET可移植类库解决方案.从Json.NET 4.5 Release 10(源代码+二进制文件)下载项目时,可以在Source\Src\Newtonsoft.Json.Portable中找到解决方案.

基本上他们正在使用自定义属性提供程序的方法

//不要使用Serializable

#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
  [Serializable]
#endif
Run Code Online (Sandbox Code Playgroud)

//使用自定义提供程序

#if NETFX_CORE || PORTABLE
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
#endif 
Run Code Online (Sandbox Code Playgroud)

如果项目是PORTABLE

#if !PocketPC && !NET20
      DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
      if (dataContractAttribute != null)
        return MemberSerialization.OptIn;
#endif
Run Code Online (Sandbox Code Playgroud)

其中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,
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

更新2

我使用[DataContract]而不是[Serializable]丢失任何能力,还是我仍然可以做[Serializable]支持的所有功能?

您可以执行Serializable支持的所有操作,除了在设置名称和顺序之外控制对象的序列化方式.

使用DataContractSerializer有几个好处:

序列化任何装饰有的东西,[DataMember]即使它不是公开可见的

除非你明确告诉它("选择加入"),否则无法序列化任何内容

您可以使用上面的[Order=]属性定义元素序列化的顺序[DataMember]

不需要无参数构造函数来进行反序列化

比XmlSerializer快10%.

在这里阅读更多:XmlSerializer与DataContractSerializer

也供参考:

DataContract 支持在默认模式下对以下类型的序列化:CLR内置类型

字节数组,DateTime,TimeSpan,GUID,Uri,XmlQualifiedName,XmlElement和XmlNode数组

枚举

标有DataContract或CollectionDataContract属性的类型

实现IXmlSerializable的类型

数组和集合类,包括List,Dictionary和Hashtable

标有Seri​​alizable属性的类型,包括实现ISerializable的类型

没有上述属性(POCO)但具有默认构造函数的类型


Ste*_*ner 10

你可以做的一件事是消除常量预处理程序指令导致的混乱是将其推送到一个新SerializableAttribute类并基本上欺骗编译器.

#if PORTABLE
namespace System
{
   public class SerializableAttribute : Attribute
   {
       //this does nothing
   }  
}
#endif
Run Code Online (Sandbox Code Playgroud)

然后继续Serializable正常装饰您的课程......

  • 谢谢!但是,使用此解决方案,串行功能将被遗漏,对吧? (4认同)