【问题标题】:Create object based on XmlChoiceIdentifier基于 XmlChoiceIdentifier 创建对象
【发布时间】:2013-05-26 16:22:18
【问题描述】:

我正在使用 Activator(C#) 动态创建对象,其中一个类如下所示:

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
}

当我使用 Activator 创建 Driver 类的实例时,我得到以下对象:

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

ItemElementName是默认设置的,因为它的枚举,但是如果它基于这个枚举怎么设置Item呢? 再一次,我正在使用 Activator 动态创建许多对象,所以我无法对其进行硬编码 - 可以在类中获取此信息并正确创建 Item 属性吗?

非常感谢!

【问题讨论】:

    标签: c# reflection xml-serialization activator


    【解决方案1】:

    ItemElementName 设置为ItemChoiceType.Bit16,因为这是枚举中的第一项。因此它的值为0,但您可以将其视为Bit16。通过Activator,您创建了一个新实例。如果您不输入参数来设置属性,那么它们的值将是默认值。

    我看到你有 XmlChoiceIdentifier 和其他 XmlSerializer 的东西。该属性的目的是:

    1. 不要序列化ItemElementName 属性。
    2. 反序列化后根据Item的序列化值恢复ItemElementName

    这就是我可以根据给定的信息告诉你的......

    这是一个使用 XmlSerializer 和 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 2016-05-30
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多