2009-03-06 10 views
1

Ich entwickle einen Viewer, der in der Lage ist, alle benutzerdefinierten Dokumente zu öffnen, die wir mit unserer Software erstellen. Alle Dokumente erben von IDocument, aber ich bin mir nicht sicher, wie man mit der Deserialisierung umgehen soll (auf eine gute Art und Weise - verschachtelter Versuch/Fang könnte wahrscheinlich funktionieren, aber das wäre abscheulich).Casting auf mehrere (unbekannte Typen) zur Laufzeit

So ist meine Methode, wie es sieht nun wie folgt lautet:

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

Offensichtlich ist dies nicht funktioniert, da ich nicht die Variable docType auf diese Weise verwenden können, aber ich denke, es ist der Punkt, was zeigt I versuche ich zu tun. Was wäre der richtige Weg, um das zu tun?

bearbeiten> @John ok, vielleicht sollte ich noch eine Frage anhängen: wenn ich eine Schnittstelle:

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

und eine Klasse:

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

    public Int32 DerivedOnlyInt; 
} 

, wenn ich zu einem IDocument deserialisieren, wird der DerivedOnlyInt ein Teil des Objekts sein - so dass ich nach der Deserialisierung auf SomeDocType umwandeln kann und es wird in Ordnung sein?

Antwort

4

Warum nicht einfach auf IDocument werfen? Welchen Nutzen hätten Sie hier, um den genauen Typ zu erreichen?

Wenn Sie wollen, dass der Anrufer das Ergebnis in einer stark typisierten Weise zu bekommen, hier ist, wie ich es schreiben würde, mit Generika:

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

natürlich, dass die richtige Art zu wissen, auf den Anrufer beruht auf Kompilierzeit. Wenn sie dies nicht tun, es gibt keinen Weg werden sie wissen, wie man Verwendung die richtige Art sowieso, also nur zurück IDocument:

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

EDIT: Um die Bearbeitung auf Ihre Frage zu beantworten, ja die abgeleitete Eigenschaft würde noch existieren. Casting verändert ein Objekt nicht wirklich - es bedeutet nur, dass Sie eine Referenz erhalten, von der der Compiler weiß, dass sie von einem geeigneten Typ ist.

+0

Ich verwende einen generischen Ansatz, um meine Serialisierungsfunktionen zu umhüllen. Dies ist der beste Weg IMHO – JoshBerke

+0

Sehr schön. Der Aufrufer kennt in diesem Fall den Dokumententyp (über die Dateiendung aus dem openfiledialog). Danke Jon –

+0

@ Jon das scheint nicht für XmlSerialization zu arbeiten. Ich konnte eine Frage bekommen und antworte das funktioniert aber fühlt sich ein bisschen klatschig an, fehlt uns was: http://stackoverflow.com/questions/1145791/xml-object-deserialization-to-interface – ahsteele

1

Sie verwenden die BinaryFormatter-Klasse, die Informationen in den serialisierten Streams enthält geben, so dass Sie brauchen nicht die docType Variable:

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

Wenn Sie leicht herausfinden, welche Art von Dokument es sich handelt (dh : Es ist Teil des Dateiheaders), es könnte am einfachsten sein, eine strategy für Deserialisierung, die für jeden Typ spezifisch ist.

Verwandte Themen