web-dev-qa-db-ja.com

ポータブルクラスライブラリ:[Serializable]の推奨代替品

.NET Framework C#クラスライブラリをポータブルクラスライブラリに移植しています。繰り返し発生する問題の1つは、[Serializable]属性で装飾されたクラスの処理方法です。この属性は、Portable Class Libraryサブセットの一部ではないためです。代わりに、Portable Class Libraryサブセットのシリアル化機能は、 DataContractAttribute でカバーされているように見えます。

  • ポータブルクラスライブラリで可能な限り多くの機能を保持するには、[Serializable][DataContract]属性に置き換えるだけで十分です(シリアル化の対象となるすべてのフィールドとプロパティを装飾する必要があることを意味します) [DataMember]も))?
  • (もしあれば)私はnotcan[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; }

        ...
    }
43

Portable Class Libraries(PCL)が正式に非推奨になりました[2017年8月16日]

現在、さまざまな.NET実装間でコードを共有している場合は、おそらくポータブルクラスライブラリ(PCL)を知っているでしょう。 .NET Standard 2.0のリリースに伴い、PCLは正式に廃止されました。プロジェクトを.NET Standardに移行する必要があります。

出典:。NET Standard 2.0の発表

すべてのプラットフォームでポータブルクラスライブラリ(PCL)が利用可能に[2013年10月14日]

本日のリリース以前は、PCL参照アセンブリにはライセンス制限があり、Windowsでしか使用できませんでした。本日のリリースでは、マイクロソフト以外のプラットフォームを含むすべてのプラットフォームでを使用できるライセンスを備えたPCLリファレンスアセンブリの新しいスタンドアロンリリースを発表します。これにより、開発者はさらに柔軟になり、.NETで素晴らしいことができます。

出典:Portable Class Library(PCL)がすべてのプラットフォームで利用可能になりました

ダウンロード: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属性。

[〜#〜] update [〜#〜]

はい。

Json.NET ポータブルクラスライブラリソリューションの実装方法を確認できます。ここからプロジェクトをダウンロードすると、Source\Src\Newtonsoft.Json.Portableでソリューションを見つけることができます Json.NET 4.5 Release 10(ソース+バイナリ)

基本的に、カスタム属性プロバイダーを使用したアプローチを使用しています

// 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

[Serializable]の代わりに[DataContract]を使用して能力を失いましたか、それとも[Serializable]がサポートするすべてを実行できますか?

Serializableがサポートするすべてのことを行うことができます。ただし、名前と順序の設定以外でオブジェクトをシリアル化する方法の制御は除きます。

DataContractSerializer を使用すると、いくつかの利点があります。

[DataMember]で装飾されたものはすべて、それが公開されていなくてもシリアル化する

( "opt-in")を特に指定しない限り、何もシリアル化できません。

[Order=][DataMember]属性を使用して、要素がシリアル化される順序を定義できます

逆シリアル化のためにパラメータなしのコンストラクタを必要としません

xmlSerializerよりも10%高速です。

詳細はこちら: XmlSerializer vs DataContractSerializer

参照用:

DataContractは、デフォルトモードで以下の種類の型のシリアル化をサポートします。CLR組み込み型

バイト配列、DateTime、TimeSpan、GUI​​D、Uri、XmlQualifiedName、XmlElementおよびXmlNode配列

列挙型

DataContractまたはCollectionDataContract属性でマークされたタイプ

IXmlSerializableを実装する型

List、Dictionary、Hashtableなどの配列およびコレクションクラス

ISerializableを実装するものを含むSerializable属性でマークされた型

上記の属性(POCO)を持たないが、デフォルトのコンストラクターを持つ型

43
Matija Grcic

定数プリプロセッサディレクティブが引き起こす混乱を解消するためにできることの1つは、それを1つの新しいSerializableAttributeクラスにプッシュし、基本的にコンパイラをだますことです。

#if PORTABLE
namespace System
{
   public class SerializableAttribute : Attribute
   {
       //this does nothing
   }  
}
#endif

その後、通常どおりSerializableを使用してクラスを装飾し続けます...

10
Steve Danner

.Net 4.6以降では、DataContractはPCLで使用できなくなりました。ここで利用可能なNugetパッケージSystem.Runtime.Serialization.Primitivesを追加する必要があります。 https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/

実際のシリアル化については、System.Runtime.Serialization.Json、System.Runtime.Serialization.Xml、Newtonsoft.Jsonなどの実装もおそらく必要になることに注意してください。

2
Lex