C#Reflection:如何从基类中获取派生类的属性

时间:2010-09-28 18:16:48

标签: c# reflection

基本上我只想从基类中使用[Test]属性获取派生类的属性。

以下是我的示例代码:

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();
        }
    }
}

我希望xmlNode是这样的:

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

谢谢

2 个答案:

答案 0 :(得分:8)

您可以致电this.GetType().GetProperties()并在每个GetCustomAttributes()上致电PropertyInfo以查找具有该属性的属性。

您需要递归运行循环以扫描基类型的属性。

答案 1 :(得分:2)

我不认为XmlNode是一个很好的课程。 首先,创建一个XmlNode需要你为它传递一个XmlDocument,这不是一个美丽的解决方案

其次,可以使用LINQ很好地提取属性和属性值,我认为这可以很好地与LINQ to XML(特别是XElement类)集成。

我写了一些代码:

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 ());
    }
}

这将以下XML输出到控制台:

<class name="DerivedClass">
  <field name="Name" value="Johnny" />
  <field name="Id" value="42" />
</class>