2009-03-06 7 views
1

Je suis en train de développer une visionneuse qui sera capable d'ouvrir tous les documents personnalisés que nous produisons via notre logiciel. Tous les documents héritent de IDocument, mais je ne sais pas comment procéder pour désérialiser (dans le bon sens, try/catch imbriqué pourrait probablement marcher, mais ce serait hideux).lancer vers plusieurs (types inconnus) à l'exécution

donc ma méthode car il est ressemble maintenant à ceci:

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; 
} 

Il est évident que cela ne fonctionne pas comme je ne peux pas utiliser la variable docType façon, mais je pense qu'il illustre le point de ce que je j'essaie de faire. Quelle serait la bonne façon d'y arriver?

modifier> ok @John , peut-être que je devrais ajouter une autre question: si j'ai une interface:

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

et une classe:

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

    public Int32 DerivedOnlyInt; 
} 

si je deserialize à un IDocument, Le DerivedOnlyInt sera-t-il une partie de l'objet - de sorte qu'après la désérialisation, je peux lancer vers SomeDocType et tout ira bien?

Répondre

4

Pourquoi ne pas simplement convertir en IDocument? Quel avantage croyez-vous en coulant au type exact aurait ici?

Si vous voulez l'appelant pour obtenir le résultat d'une manière fortement typé, voici comment je l'écrire, en utilisant les génériques:

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); 
    } 
} 

Bien sûr, qui repose sur l'appelant de connaître le type à droite à la compilation. Si elles ne le font pas, il n'y a aucun moyen qu'ils vont savoir comment utiliser le bon type de toute façon, donc juste retour IDocument:

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

EDIT: Pour répondre à la modifier à votre question, oui la dérivée la propriété existerait toujours. La conversion ne change pas réellement un objet - cela signifie simplement que vous obtenez une référence que le compilateur sait être d'un type approprié.

+0

J'utilise une approche générique pour encapsuler mes fonctions de sérialisation. C'est la meilleure façon IMHO – JoshBerke

+0

Très agréable. L'appelant dans ce cas connaît le type de document (via l'extension de fichier de openfiledialog). Merci Jon –

+0

@Jon cela ne semble pas fonctionner pour XmlSerialization. J'ai été en mesure d'obtenir une question et une réponse qui fonctionne, mais se sent un peu kludgy, avons-nous quelque chose qui manque: http://stackoverflow.com/questions/1145791/xml-object-deserialization-to-interface – ahsteele

1

Vous utilisez la classe BinaryFormatter qui comprend des informations de type dans le flux sérialisé, de sorte que vous n'avez pas besoin de la variable 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

Si vous pouvez facilement savoir quel genre de document, il est (à savoir : il fait partie de l'en-tête du fichier), il peut être plus facile d'avoir un strategy pour la désérialisation spécifique à chaque type.

Questions connexes