Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set Xml serialization attributes per instance (or per type) with generic classes

I have a class (more complex, but simplified for the example) like this:

public class MyClass {
   public MyClass() { }

   [XmlAttribute("somename")]
   public String MyString { get; set; }

   [XmlElement("AString")]
   public List<String> TheList { get; set; }

   // Other uninteresting methods and private members.
}

Xml Serialization works fine. What I'd like to do (if it isn't too crazy) is change this class to use generics so that I can have "TheList" use different types. What I want is for the XmlElement name to be able to be specified per instance (or per type) somehow.

Ideal would be something where the name is set when the instance is created. It would be nice to macro replace the attribute parameter strings on creation, but I have no idea if anything similar is possible. Maybe it would look something like:

public class MyClass<T, (MagicalMacro)> {
   // Some kind of constructor, methods, whatever as needed.
   // MyString as above.

   [XmlElement(MagicalMacro)] // This does not compile.
   public List<T> TheList { get; set; }

   // Etc.
}
...
MyClass<int, (MagicalMacro)> myClass = new MyClass<int, "AnInteger">();

Less ideal but still satisfactory would be to name the "TheList" output name based on the type of T.

public class MyClass<T> {
   // Same constructor and MyString as the first example.

   [XmlElement(typeof(T).Name)] // This does not compile - string not constant.
   public List<T> TheList { get; set; }

   // Etc.
}

Thanks.

like image 650
Steven Avatar asked Feb 16 '26 00:02

Steven


1 Answers

Attributes need literals. The way to approach this is by using XmlAttributeOverrides to configure it at runtime, and pass that to the XmlSerializer constructor. However: cache and re-use the serializer instances when you do this, or you will leak dynamically generated assemblies.

like image 133
Marc Gravell Avatar answered Feb 17 '26 13:02

Marc Gravell