私の知る限り、さまざまな属性(Serializable
、DataContract
)をチェックしたり、Type.IsSerializable
(属性の存在をチェックするための便利な方法だと思います)をチェックしたとしても、実装が実際にシリアライズ可能Serializable
であることは保証されません。(編集:前述のように、質問で提供されているサンプルコードに見られるように、属性の装飾に依存しません。したがって、これらのフラグをチェックしても意味がありません。)XmlSerializer
Serializable
私の経験では、アプリケーションで使用されているさまざまな型を検証する単体テストを使用し、try/catch を使用して成功/失敗するかどうかを確認することをお勧めします。実行時に、(毎回事前チェックするのではなく) try/catch を使用し、例外をログに記録/処理します。
単体テストの結果として有効な互換性のある型のリストがある場合は、以前のT
テストで決定したコンパイル時のリストに対して事前チェックを行い、他の型はまったく役に立たないと想定できます。既知の有効な型のサブクラスを監視したい場合がありますが、有効なシリアル化可能な型から継承したとしても、それらの実装はそうではない可能性があります。
編集: これは Windows Phone 8 用であるため、そのプラットフォームの経験はありませんが、Silverlight を使用しました。その場合、オブジェクトがマークされていなくてもシリアル化できます[Serializable]
(実際、Silverlight には存在しません)。ビルトインXmlSerializer
は、装飾に関係なく、すべてのパブリック プロパティに対して機能します。シリアル化可能かどうかを確認する唯一の方法は、シリアル化を試みて失敗を試行/キャッチするか、各プロパティを (および子オブジェクトを介して再帰的に) 検査し、各型をシリアル化できるかどうかを確認するアルゴリズムを作成することです。
EDITx2: あなたObjectStorageHelper
の を見て、単純にシリアル化を試みて、失敗をキャッチすることをお勧めします。必ずしも例外を直接バブルアップする必要はありません。独自のカスタム例外でラップするか、シリアライゼーションの成功/失敗と失敗した理由を API コンシューマーに通知する結果オブジェクトを返すことができます。毎回高価なチェックを行うよりも、呼び出し元が有効なオブジェクトを使用していると想定することをお勧めします。
EDITx3: save メソッドで他の多くの作業を行っているため、コードを次のように書き直すことをお勧めします。
public async Task SaveAsync(T Obj)
{
if (Obj == null)
throw new ArgumentNullException("Obj");
StorageFile file = null;
StorageFolder folder = GetFolder(storageType);
file = await folder.CreateFileAsync(FileName(Obj), CreationCollisionOption.ReplaceExisting);
IRandomAccessStream writeStream = await file.OpenAsync(FileAccessMode.ReadWrite);
using (Stream outStream = Task.Run(() => writeStream.AsStreamForWrite()).Result)
{
try
{
serializer.Serialize(outStream, Obj);
}
catch (InvalidOperationException ex)
{
throw new TypeNotSerializableException(typeof(T), ex);
}
await outStream.FlushAsync();
}
}
このようにして、シリアライゼーションの問題を具体的に把握し、無効な/シリアライズ不可能なオブジェクトを提供したことを API コンシューマーに非常に明確に報告できます。このようにして、I/O 部分の一部として例外がスローされた場合、問題がどこにあるかがより明確になります。実際、シリアライゼーション/デシリアライゼーションの側面を独自の個別のメソッド/クラスに分離して、他のシリアライザーをフィードできるようにすることもできます (または、スタック トレースから問題をより明確にするか、単にメソッドに 1 つを実行させることができます)。しかし、これ以上のリライト/リファクタリングは、実際にはコードレビューに残され、目前の質問にはあまり有効ではありません.
参考までに、ユーザーが null を渡した場合、実際には何も起こらなかったときに保存が成功したと見なし、値が後で読み込まれないときに値が利用可能であると期待する可能性があるため、入力オブジェクトにも null チェックを入れました。ある。null を有効な値として許可する場合は、チェックでエラーがスローされることを気にしないでください。