2009-03-06 7 views
1

私たちのソフトウェアで作成したすべてのカスタムドキュメントを開くことができるビューアを開発しています。すべてのドキュメントはIDocumentから継承していますが、デシリアライズの方法についてはわかりません(ネストされたtry/catchはうまくいくかもしれませんが、それは恐ろしいことでしょう)。実行時に複数の(不明なタイプ)にキャストする

だから、次のようになりますされて、私の方法は:

public Boolean OpenDocument(String filename, Type docType, out IDocument document) 
{ 
    // exception handling etc. removed for brevity 

    FileStream fs = null; 
    BinaryFormatter bFormatter = new BinaryFormatter(); 

    fs = new FileStream(filename, FileMode.Open); 
    document = (docType)bFormatter.Deserialize(fs); 

    return true; 
} 

私はそのように変数のDOCTYPEを使用することはできませんとして明らかにこれは動作しませんが、私はそれがどのようなIのポイントを示していると思いますやろうとしている。それについて正しい方法は何でしょうか?

編集> [OK]を@ジョン 、多分私は別の質問追加する必要があります。

public interface IDocument 
{ 
    public Int32 MyInt { get; } 
} 

とクラス::私はインターフェイスがあれば を私はIDocumentにデシリアライズ場合

public class SomeDocType : IDocument 
{ 
    protected Int32 myInt = 0; 
    public Int32 MyInt { get { return myint; } } 

    public Int32 DerivedOnlyInt; 
} 

を、 DerivedOnlyIntはオブジェクトの一部になります。つまり、デシリアライズ後にSomeDocTypeにキャストしても問題ありません。

答えて

4

IDocumentにキャストしてみませんか?正確なタイプへのキャスティングがここにあったとすれば、どんなメリットがありますか?

あなたは、呼び出し側が強く型付けされた方法で結果を取得したい場合は、ここでジェネリックを使用して、私はそれを書くだろう方法は次のとおりです。もちろん

public T OpenDocument<T>(String filename) where T : IDocument 
{ 
    using (FileStream fs = new FileStream(filename, FileMode.Open)) 
    { 
     BinaryFormatter bFormatter = new BinaryFormatter();  
     return (T) bFormatter.Deserialize(fs); 
    } 
} 

、それはで右のタイプを知って、発信者に依存していますコンパイル時。

public IDocument OpenDocument(String filename) 
{ 
    using (FileStream fs = new FileStream(filename, FileMode.Open)) 
    { 
     BinaryFormatter bFormatter = new BinaryFormatter();  
     return (IDocument) bFormatter.Deserialize(fs); 
    } 
} 

EDIT:あなたの質問に編集に答えるために、はい派生そうではない場合、彼らはこれだけIDocumentを返す方法使用右タイプとにかく、知っているつもりだ方法はありませんプロパティはまだ存在します。キャストは実際にオブジェクトを変更するものではなく、コンパイラが適切な型であることがわかっている参照を取得することを意味します。

+0

私はシリアル化関数をラップするための一般的なアプローチを使用します。これが最善の方法です。IMHO – JoshBerke

+0

とてもいいです。この場合、呼び出し元は(openfiledialogのファイル拡張子を介して)文書タイプを知っています。ありがとうJon –

+0

@ジョンこれはXmlSerializationのために動作していないようです。私は質問と答えを得ることができたが動作するが、少しkludgy感じ、私たちは何かが欠けている:http://stackoverflow.com/questions/1145791/xml-object-deserialization-to-interface – ahsteele

1

あなたはシリアル化されたストリームに情報を入力含んにBinaryFormatterクラスを使用しているので、あなたはDOCTYPE変数は必要ありません。

public Boolean OpenDocument(String filename, out IDocument document) 
{ 
    // exception handling etc. removed for brevity 

    FileStream fs = null; 
    BinaryFormatter bFormatter = new BinaryFormatter(); 

    fs = new FileStream(filename, FileMode.Open); 
    document = (IDocument)bFormatter.Deserialize(fs); 

    return true; 
} 
1

あなたは簡単にそれが(つまり、ある文書の種類を把握することができた場合それはファイルヘッダーの一部です)、各タイプに固有のデシリアライズ用にstrategyを持つのが最も簡単です。