代码之家  ›  专栏  ›  技术社区  ›  Jeremy

在代码生成(通过xsd.exe)类中调用子类属性

  •  1
  • Jeremy  · 技术社区  · 15 年前

    我试图从一个XSD生成代码,该XSD有两个扩展公共complexType的complexType。继承者有一个名为“value”的公共属性,该属性具有不同的类型。当然,由于XSD规则,我不能将它放在我的基类型上。我的意图是以多态方式调用基类型上的属性,这将调用子类上的正确方法。这可能吗?

    这是我的XSD

    <xs:complexType name="Property">
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
    <xs:complexType name="StringProperty">
        <xs:complexContent>
            <xs:extension base="Property">
                <xs:attribute name="value" type="xs:string" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="BooleanProperty">
        <xs:complexContent>
            <xs:extension base="Property">
                <xs:attribute name="value" type="xs:boolean" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    

    这将生成以下代码:

    public partial class Property {
    
        private string nameField;
    
        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string name {
            get {
                return this.nameField;
            }
            set {
                this.nameField = value;
            }
        }
    }
    
    public partial class StringProperty : Property {
    
        private string valueField;
    
        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string value {
            get {
                return this.valueField;
            }
            set {
                this.valueField = value;
            }
        }
    }
    
    public partial class BoolProperty : Property {
    
        private bool valueField;
    
        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public bool value {
            get {
                return this.valueField;
            }
            set {
                this.valueField = value;
            }
        }
    }
    

    我想做的是:

                // ConfigProperties is an array of Property objects
                foreach (Property property in config.ConfigProperties)
                {
                    // Doesn't compile since Property.value doesn't exist in the base class.
                    Console.WriteLine(property.value);
                }
    

    我尝试在property对象上实现一个“value”getter属性,希望子类的“value”属性定义能够隐藏它,但这并不能解决问题:

    public partial class Property
    {
        public virtual string value
        {
            get { throw new NotImplementedException(); } // this method is called instead of the Property subclass methods
        }
    }
    

    后续问题编辑 当前位置这些答案证实了我的担心,这是不可能的。但是否仍有可能以某种方式执行以下操作:

                foreach (Property property in config.ConfigProperties)
                {
                    somevalue = property.GetValue();
                }
    

    其中GetValue()是一个方法,通过它实际使用的属性的子类来确定它应该具有什么样的返回类型?请原谅我太懒了。我相信这一点 it's a virtue . =)

    2 回复  |  直到 15 年前
        1
  •  2
  •   Jan Jongboom    15 年前

    Property 对象,因此序列化程序创建该类型的对象 . 在运行时,您将不知道是否有 BoolProperty StringProperty .

    StringProperty

    财产 . 然后,只要您创建一个 virtual property 在实现类中重写的基类上。


    对作者编辑的回应
    在那一点上正确的信息。您必须将对象显式反序列化为 StringProperty 让.NET识别您的财产。您将永远无法检测函数中的propertytype。

    如果你有 财产

    public string GetValue(this Property property)
    {
        if(property is StringProperty) return ((StringProperty)property).Value;
        else if ...
    }
    

    财产 物体。

        2
  •  1
  •   Ciprian Bortos    15 年前

    我认为不可能像你那样做。

    例如,您可以为属性分部类添加另一个文件,并添加一个名为“public virtual string ValueToString()”的虚拟方法,在StringProperty和BoolProperty中重写它(也可以通过分部类机制)。这样,您就可以使foreach工作(调用property.ValueToString())。