Je porte une bibliothèque de classes .NET Framework C # vers une bibliothèque de classes portable. Un problème récurrent est de savoir comment gérer les classes décorées avec le [Serializable]
attribut, car cet attribut ne fait pas partie du sous-ensemble de la bibliothèque de classes portable. La fonctionnalité de sérialisation du sous-ensemble de la bibliothèque de classes portable semble plutôt être couverte par DataContractAttribute .
[Serializable]
avec le [DataContract]
attribut (avec l'implication que tous les champs et propriétés soumis à la sérialisation devraient être décorés avec [DataMember]
ainsi que)?[Serializable]
appliqué?Étant donné que [DataContract]
et [DataMember]
sont utilisés, j'envisage de changer le code selon les lignes suivantes. Y a-t-il des défauts évidents avec cette approche? Existe-t-il un moyen de formuler la même chose moins verbeuse?
#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; }
...
}
Les bibliothèques de classes portables (PCL) sont désormais officiellement obsolètes [16 août 2017]
Si vous partagez du code entre différentes implémentations .NET aujourd'hui, vous connaissez probablement les bibliothèques de classes portables (PCL). Avec la sortie de .NET Standard 2.0, nous déconseillons maintenant officiellement les PCL et vous devez déplacer vos projets vers .NET Standard.
Source: Annonce de la norme .NET 2.
Bibliothèque de classes portable (PCL) désormais disponible sur toutes les plates-formes [14 oct. 2013]
Avant la sortie d'aujourd'hui, il y avait une restriction de licence avec les assemblys de référence PCL, ce qui signifiait qu'ils ne pouvaient être utilisés que sous Windows. Avec la version d'aujourd'hui, nous annonçons une nouvelle version autonome des assemblys de référence PCL avec une licence qui lui permet d'être utilisée sur n'importe quelle plate-forme - y compris celles non Microsoft. Cela permet aux développeurs encore plus de flexibilité et de faire de grandes choses avec .NET.
Source: Bibliothèque de classes portable (PCL) désormais disponible sur toutes les plateformes
Téléchargement: Microsoft .NET Portable Library Reference Assemblies 4.6 RC
Juste à titre de référence, l'ensemble d'assemblages autorisé est:
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 (de Silverlight)
Autant que je sache, vous devez marquer les champs avec l'attribut DataMember et ajouter l'attribut DataContract attribut.
[~ # ~] mise à jour [~ # ~]
Oui.
Vous pouvez voir comment Json.NET solution de bibliothèque de classes portable est implémentée. Vous pouvez trouver la solution dans le Source\Src\Newtonsoft.Json.Portable lorsque vous téléchargez le projet à partir d'ici Json.NET 4.5 Release 10 (source + binaire) .
Fondamentalement, ils utilisent une approche avec un fournisseur d'attributs personnalisés
// n'utilise pas Serializable
#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
[Serializable]
#endif
// utilise un fournisseur personnalisé
#if NETFX_CORE || PORTABLE
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
#endif
Et si le projet est [~ # ~] portable [~ # ~]
#if !PocketPC && !NET20
DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
if (dataContractAttribute != null)
return MemberSerialization.OptIn;
#endif
où la description OptIn est:
/// <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,
J'espère que cela aide.
MISE À JOUR 2
Suis-je en train de perdre des capacités en utilisant [DataContract] au lieu de [Serializable], ou serai-je toujours en mesure de faire tout ce que [Serializable] prend en charge?
Vous pouvez faire tout ce que Serializable prend en charge, sauf le contrôle de la façon dont l'objet est sérialisé en dehors de la définition du nom et de la commande.
L'utilisation de DataContractSerializer présente plusieurs avantages:
sérialiser tout ce qui est décoré d'un [DataMember]
même s'il n'est pas visible par le public
ne peut rien sérialiser sauf si vous le lui demandez spécifiquement ("opt-in")
vous pouvez définir l'ordre dans lequel les éléments sont sérialisés en utilisant le [Order=]
attribut sur le [DataMember]
ne nécessite pas de constructeur sans paramètre pour la désérialisation
est 10% plus rapide que XmlSerializer.
En savoir plus ici: XmlSerializer vs DataContractSerializer
Aussi pour la référence:
DataContract
prend en charge la sérialisation des types de types suivants dans le mode par défaut: types intégrés CLR
Tableau d'octets, DateTime, TimeSpan, GUID, Uri, XmlQualifiedName, XmlElement et XmlNode
Enums
Types marqués avec l'attribut DataContract ou CollectionDataContract
Types qui implémentent IXmlSerializable
Tableaux et classes de collection, y compris List, Dictionary et Hashtable
Types marqués avec l'attribut Serializable, y compris ceux qui implémentent ISerializable
Types sans aucun des attributs ci-dessus (POCO) mais avec un constructeur par défaut
Une chose que vous pourriez faire pour éliminer l'encombrement causé par les directives constantes du préprocesseur est de pousser cela vers une nouvelle classe SerializableAttribute
et de tromper le compilateur.
#if PORTABLE
namespace System
{
public class SerializableAttribute : Attribute
{
//this does nothing
}
}
#endif
Continuez ensuite à décorer vos classes avec Serializable
comme d'habitude ...
Pour .Net 4.6 et versions ultérieures, DataContract n'est plus disponible pour PCL. Vous devez ajouter le package Nuget System.Runtime.Serialization.Primitives disponible ici: https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/
Remarque pour la sérialisation réelle, vous aurez probablement également besoin d'une implémentation telle que System.Runtime.Serialization.Json, System.Runtime.Serialization.Xml ou un Newtonsoft.Json.