2009-11-04 8 views
14

ISerializableインターフェイスをC#で実装するときは、SerializationInfoオブジェクトを取得し、さまざまなGetInt32,GetObjectなどのメソッドを使用してクエリを実行して、逆シリアル化しようとしているオブジェクトのフィールドを埋めるコンストラクタを提供します。SerializationInfoにTryGetValueメソッドがないのはなぜですか?

[Serializable]属性を使用するのではなく、このインターフェイスを実装する主な理由の1つは、下位互換性のためです。クラスに新しいフィールドを追加した場合、シリアル化された古いバージョンによってSerializationExceptionがキャッチされます適切な方法でそれらを扱う。

私の質問は次のとおりです。なぜ、本質的にコントロールフローなのか、これらの例外を使用する必要がありますか?しばらく前に保存された多数のクラスを逆シリアル化すると、各クラスの各フィールドが欠落すると例外がスローされ、実際にはパフォーマンスが低下します。

SerializationInfoクラスでは、TryGetValueメソッドが提供されないため、名前文字列が存在しない場合は単にfalseを返します。

+0

誰を確認する:「..それはMS宛だ推測を必要としている人のための

私の実装をm個そのクラスを実装 –

+4

おそらくここにいる:P –

答えて

23

あなたが利用可能なフィールドを反復処理し、しかしswitchを、使用することができます...

  foreach(SerializationEntry entry in info) { 
       switch(entry.Name) { 
        ... 
       } 
      } 

またはあなたがいるProtobufネット;-pが

+2

クール;これはVS2008のドキュメントには書かれていないようです。 –

+1

合意。これはどこにも書かれていないようです。 SerializationInfoが列挙可能であるとは言えません。しかし、それは私のために働いた。 –

+1

@Michaelもちろん、[ここ](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator.aspx)、または(@Joel)1.1に戻る[ここに](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator(v = VS.71).aspx) –

0

がまあ誰もが「なぜ」答えない使用することができますが、私

public static class SerializationInfoExtensions 
{ 
    public static bool TryGetValue<T>(this SerializationInfo serializationInfo, string name, out T value) 
    { 
     try 
     { 
      value = (T) serializationInfo.GetValue(name, typeof(T)); 
      return true; 
     } 
     catch (SerializationException) 
     { 
      value = default(T); 
      return false; 
     } 
    } 

    public static T GetValueOrDefault<T>(this SerializationInfo serializationInfo, string name, Lazy<T> defaultValue) 
    { 
     try 
     { 
      return (T) serializationInfo.GetValue(name, typeof(T)); 
     } 
     catch (SerializationException) 
     { 
      return defaultValue.Value; 
     } 
    } 
} 
関連する問題