tags:

views:

76

answers:

2

Hello,

Basically I just want to get the properties of the derived class with [Test] attribute from the base class.

Here is my sample code:

namespace TestConsole
{
    public class BaseClass
    {
        private System.Int64 _id;

        public BaseClass()
        { }

        [Test]
        public System.Int64 ID
        {
            get { return _id;}
            set { _id = value;}
        }

        public System.Xml.XmlNode ToXML()
        { 
            System.Xml.XmlNode xml = null;

            //Process XML here

            return xml;
        }
    }

    public class DerivedClass : BaseClass
    {
        System.String _name;

        public DerivedClass()
        { }

        [Test]
        public System.String Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }

    public class TestConsole
    {
        public static void main()
        {
            DerivedClass derivedClass = new DerivedClass();

            System.Xml.XmlNode xmlNode = derivedClass.ToXML();
        }
    }
}

I want the xmlNode to be something like this:

<root>
  <class name="DerivedClass">
    <Field name="Id">
    <Field name="Name">
  </class>
</root>

Thank you

+6  A: 

You can call this.GetType().GetProperties() and call GetCustomAttributes() on each PropertyInfo to find properties that have the attribute.

You will need to run the loop recursively to scan the properties of the base type.

SLaks
+1  A: 

I do not think that XmlNode is a good class for this purpose. Firstly, creating an XmlNode requires you to pass an XmlDocument for it, which is not a beatiful solution.

Secondly, attributes and property values can be nicely extracted with LINQ and I think that this might integrate nicely with LINQ to XML (and, specifically, XElement class).

I wrote some code that does it:

using System;
using System.Linq;
using System.Xml.Linq;

[AttributeUsage(AttributeTargets.Property)]
class PropertyAttribute : Attribute { }

class BaseClass
{
    [Property]
    public int Id { get; set; }

    IEnumerable<XElement> PropertyValues {
        get {
            return from prop in GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
                   where prop.GetGetMethod () != null
                   let attr = prop.GetCustomAttributes(typeof(PropertyAttribute), false)
                                  .OfType<PropertyAttribute>()
                                  .SingleOrDefault()

                   where attr != null
                   let value = Convert.ToString (prop.GetValue(this, null))

                   select new XElement ("field",
                       new XAttribute ("name", prop.Name),
                       new XAttribute ("value", value ?? "null")
                   );
        }
    }

    public XElement ToXml ()
    {
        return new XElement ("class",
               new XAttribute ("name", GetType ().Name),
               PropertyValues
               );
    }
}

class DerivedClass : BaseClass
{
    [Property]
    public string Name { get; set; }
}

public static class Program
{
    public static void Main()
    {
        var instance = new DerivedClass { Id = 42, Name = "Johnny" };
        Console.WriteLine (instance.ToXml ());
    }
}

This outputs the following XML to the console:

<class name="DerivedClass">
  <field name="Name" value="Johnny" />
  <field name="Id" value="42" />
</class>
gaearon
Oh, I just noticed you didn't need values there. You'll need to remove value retrieving section there. However I still think this code sample is useful enough.
gaearon