C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 36 を表示中)
■17850 / )  例外処理をするべきか否か
□投稿者/ 通りすがり (16回)-(2008/05/02(Fri) 13:16:22)

分類:[C#] 

ISerializableを実装してシリアライズとデシリアライズの挙動を自分で定義しようとしています。
デシリアライズ用のコンストラクタにて、SerializationInfoオブジェクトのGetValueやらGetInt32やらGet***に対して存在しない名前で値を取ってこようとすると例外が投げられますよね。
なので、自分は今現在以下の「コード1」と「コード2」の2通りを考えています。
 コード1:SerializationEntryのNameとValueをDictionaryに詰め込んでおくやり方
 コード2:逐一try-catchするやり方

これって、どちらが好ましいでしょうか?
デシリアライズの問題ではなくて、「キーの存在を確かめて操作するのがいいか」「なにも考えずtry-catchするのがいいか」に帰着すると思います。

あ、ちなみに名前が見つからなかったときは、その型のコンストラクタでもって初期化してやろうと思っています。

もっとスマートなやり方あるだろうが!ヴォケ!って場合は、是非お教え願えませんか。
自分としては、SerializationInfoにContainsName的なメソッドがあったらなぁ、と思いました。
コメントをよろしくお願いします。

////////////////////////////////////////////////////////////
// コード1
////////////////////////////////////////////////////////////
[Serializable]
class Hoge : ISerializable
{
 int _n;
 string _str;
 Foo _foo;

 public Hoge()
 {
  _n = 42;
  _str = "hoge";
  _foo = new Foo();
 }

 // デシリアライズ用
 public Hoge(SerializationInfo info, StreamingContext context)
 {
  Dictionary<string, object> entries = new Dictionary<string, object>();
  foreach (SerializationEntry entry in info)
  {
   if (!entries.ContainsKey(entry.Name)) entries.Add(entry.Name, entry.Value);
  }

  if (entries.ContainsKey("n")) _n = info.GetInt32("n");
  else _n = 0;
  if (entries.ContainsKey("str")) _str = info.GetString("str");
  else _str = string.Empty;
  if (entries.ContainsKey("foo")) _foo = info.GetValue("foo", typeof(Foo)) as Foo;
  else _foo = new Foo();
 }

 // シリアライズ用
 public void GetObjectData(SerializationInfo info, StreamingContext context)
 {
  info.AddValue("n", _n);
  info.AddValue("str", _str);
  info.AddValue("foo", _foo);
 }
}



////////////////////////////////////////////////////////////
// コード2
////////////////////////////////////////////////////////////
[Serializable]
class Hoge : ISerializable
{
 int _n;
 string _str;
 Foo _foo;

 public Hoge()
 {
  _n = 42;
  _str = "hoge";
  _foo = new Foo();
 }

 // デシリアライズ用
 public Hoge(SerializationInfo info, StreamingContext context)
 {
  // _nを初期化
  try{_n = info.GetInt32("n");}
  catch(SerializationException ex){_n = 0;}

  // _strを初期化
  try{_str = info.GetString("str");}
  catch(SerializationException ex){_str = string.Empty;}

  // _fooを初期化
  try{_foo = info.GetString("foo");}
  catch(SerializationException ex){_foo = new Foo();}
 }

 // シリアライズ用
 public void GetObjectData(SerializationInfo info, StreamingContext context)
 {
  info.AddValue("n", _n);
  info.AddValue("str", _str);
  info.AddValue("foo", _foo);
 }
}

返信 編集キー/


管理者用

- Child Tree -