Create object based on XmlChoiceIdentifier

走远了吗. 提交于 2019-12-02 08:27:04

问题


I am creating objects dynamically using Activator(C#) and one of these classes looks like:

class Driver
{
   Driver() { }

   [XmlChoiceIdentifier("ItemElementName")]
   [XmlElement("Bit16", typeof(DriverModule))]
   [XmlElement("Bit32", typeof(DriverModule))]
   [XmlElement("Bit64", typeof(DriverModule))]
   [XmlElement("Unified", typeof(DriverUnified))]
   public object Item { get; set; }
   [XmlIgnore]
   public ItemChoiceType ItemElementName { get; set; }

   // ... other serialization methods
}

When I create instance of Driver class using Activator I get following object:

obj.Item = null;
obj.ItemElementName = "Bit16"

ItemElementName is set by default, because its enum, but how to set Item if its based on this enum? Once again, I am creating many object dynamically with Activator, so I cant hardcode it - its possible to get this information in class and create Item property properly?

Thanks a lot!


回答1:


ItemElementName is set to ItemChoiceType.Bit16 because that is the first item in the enumeration. Hence its value is 0 but you can see it as Bit16. By Activator you creates a new instance. If you don't put arguments in order to set your properties, then their values will be default ones.

I see that you have there XmlChoiceIdentifier and other XmlSerializer's stuff. The purpose of this attribute is to:

  1. Do not serialize ItemElementName property.
  2. To restore ItemElementName after deserialization based on serialized value of Item.

That's what I can tell you basing on given information...

Here is an example that utilizes XmlSerializer along with XmlChoiceIdentifier:

public class Choices
{
    [XmlChoiceIdentifier("ItemType")]
    [XmlElement("Text", Type = typeof(string))]
    [XmlElement("Integer", Type = typeof(int))]
    [XmlElement("LongText", Type = typeof(string))]
    public object Choice { get; set; }

    [XmlIgnore]
    public ItemChoiceType ItemType;
}

[XmlType(IncludeInSchema = false)]
public enum ItemChoiceType
{
    Text,
    Integer,
    LongText
}

class Program
{
    static void Main(string[] args)
    {
        Choices c1 = new Choices();
        c1.Choice = "very long text"; // You can put here a value of String or Int32.
        c1.ItemType = ItemChoiceType.LongText; // Set the value so that its type match the Choice type (Text or LongText due to type of value is string).

        var serializer = new XmlSerializer(typeof(Choices));
        using (var stream = new FileStream("Choices.xml", FileMode.Create))
            serializer.Serialize(stream, c1);

        // Produced xml file.
        // Notice:
        // 1. LongText as element name
        // 2. Choice value inside the element
        // 3. ItemType value is not stored
        /*
        <?xml version="1.0"?>
        <Choices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <LongText>very long text</LongText>
        </Choices>
        */

        Choices c2;
        using (var stream = new FileStream("Choices.xml", FileMode.Open))
            c2 = (Choices)serializer.Deserialize(stream);

        // c2.ItemType is restored
    }
}


来源:https://stackoverflow.com/questions/16761223/create-object-based-on-xmlchoiceidentifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!