2010-01-13 3 views
1

Compte tenu de ce codeDataContractSerializer avec abstraite (base)/béton (héritant) des classes

public override void Serialize(BaseContentObject obj) 
{ 
    string file = ObjectDataStoreFolder + obj.Slug + ".xml"; 
    if(obj.GetType() == typeof(Page)) 
    { 
     DataContractSerializer dcs = new DataContractSerializer(typeof Page)); 
     XmlDictionaryWriter myWriter = 
      XmlDictionaryWriter.CreateTextWriter(new FileStream(file, ileMode.CreateNew, FileAccess.Write), 
              Encoding.UTF8); 
     dcs.WriteObject(myWriter, obj); 
     myWriter.Close(); 
    } 
    else if(obj.GetType() == typeof(Image)) 
    { 
     DataContractSerializer dcs = new DataContractSerializer(typeof Image)); 
     ... 
     ... 
    } 
} 

est-il un moyen de faire quelque chose comme ça

DataContractSerializer dcs = new DataContractSerializer(obj.GetType()); 
// this fails however, compiler error 

et se débarrasser de ces instructions if() au dessus? Le constructeur de DataContractSerializer s'attend à ce que Type ou Namespace, mais il ne fonctionne pas avec obj.GetType().

Ma hiérarchie de classes est la suivante:

BaseContentClass (résumé)

page (béton, BaseContentClass hérite)

image (béton, BaseContentClass hérite)

...

?

Répondre

0

Si vous parlez de cette DataContractSerializer alors le code suivant compilera fin:

DataContractSerializer dcs = new DataContractSerializer(obj.GetType()); 

Comme le constructeur attend un paramètre de type.

+0

Je viens de l'essayer de nouveau dans un autre endroit et cela fonctionne vraiment, donc je ne comprends vraiment pas où mon erreur est venue avant. Merci! – mare

3

Dites aux sérialiseur quoi anticiper:

[KnownType(typeof(Page))] 
[KnownType(typeof(Image))] 
[DataContract] 
public abstract class BaseContentObject { /* ... */ } 

[DataContract] 
public class Page : BaseContentObject { /* ... */ } 

[DataContract] 
public class Image : BaseContentObject { /* ... */ } 

vous pouvez utiliser pour tout new DataContractSerializer(typeof(BaseContentObject)).

+0

Cela semble intéressant. Cependant, sur ma classe abstraite, je n'ai actuellement pas d'attribut [DataContract] (seules les classes héritées sont décorées pour l'instant). Dois-je décorer un résumé aussi? – mare

0

Je préférerais utiliser des génériques. Le bidon d'aide ressemble à:

public static string Serialize<T>(T t, IEnumerable<System.Type> types, bool preserveReferences) 
    { 
     StringBuilder aStringBuilder = new StringBuilder(); 
     using (StringWriter aStreamWriter = new StringWriter(aStringBuilder)) 
     { 
      DataContractSerializer aDCS; 
      using (XmlTextWriter aXmlTextWriter = new XmlTextWriter(aStreamWriter)) 
      { 
       aDCS = new DataContractSerializer(typeof(T), types, int.MaxValue, false, preserveReferences, null); 

       aDCS.WriteObject(aXmlTextWriter, t); 
      } 
     } 
     return aStringBuilder.ToString(); 
    } 

Generics vous permettra de sérialiser tout type que vous voulez sans utiliser si des déclarations.

Questions connexes