属性是用户定义的?

时间:2011-01-27 07:24:38

标签: c# reflection

如果属性是用户定义的,我现在如何在使用Type.GetProperties()获得的列表中?

例如

class test
{
     public string propertyOne{get;set;}
     public string propertyTwo{get;set;}
}

使用typeof(test).GetProperties()我得到两个PropertyInfo,我现在怎么能用户定义?

有关上下文的信息,这里是应该通过的测试

    [Test]
    public void GetFullNameScalarPropertiesTest()
    {
        // Act
        var properties = ReflectionHelper.GetFullNameScalarProperties(typeof(Parent));

        // Assert
        Assert.True(properties.Contains("PropertyOne"));
        Assert.True(properties.Contains("Child.PropertyTwo"));
        Assert.True(properties.Contains("Child.GrandChild.PropertyThree"));
        Assert.That(properties.Count, Is.EqualTo(3));
    }

    class Parent
    {
        public Parent()
        {
            Child = new Child();
        }

        public string PropertyOne { get; set; }
        public Child Child { get; set; }
    }

    class Child
    {
        public Child()
        {
            GrandChild = new GrandChild();
        }

        public string PropertyTwo { get; set; }
        public GrandChild GrandChild { get; set; }
    }

    class GrandChild
    {
        public string PropertyThree { get; set; }
    }

所以,在一个递归方法中,我正在获取属性并创建一个名为

的列表

ATM通过此测试的代码是

    public static IList<string> GetFullNameScalarProperties(Type type)
    {
        var lista = new List<string>();
        var path = string.Empty;
        var properties = type.GetProperties();

        foreach (var propertyInfo in properties)
            GetFullNameScalarProperties(propertyInfo, path, lista);

        return lista;
    }

    private static void GetFullNameScalarProperties(PropertyInfo propertyInfo, string path, ICollection<string> lista)
    {
        if (!string.IsNullOrEmpty(path))
            path += ".";

        path += propertyInfo.Name;

        if (propertyInfo.PropertyType.FullName != null)
            if (propertyInfo.PropertyType.FullName.StartsWith("System"))
            {
                lista.Add(path);
                return;
            }

        var properties = propertyInfo.PropertyType.GetProperties();

        foreach (var pi in properties)
            GetFullNameScalarProperties(pi, path, lista);
    }

5 个答案:

答案 0 :(得分:2)

目前还不清楚“用户定义”是什么意思 - 您是否想要发现自动实现的属性与手工编写的属性之间的区别?如果是这样,自动实现的属性将在getter和setter上具有[CompilerGenerated]属性。

using System;
using System.Runtime.CompilerServices;

class Program
{
    public int AutomaticallyImplemented { get; set; }
    public int HandWritten {
        get { return 0; }
        set {}
    }

    static void Main()
    {
        foreach (var property in typeof(Program).GetProperties())
        {
            bool auto = property.GetGetMethod().IsDefined
                (typeof(CompilerGeneratedAttribute), false);
            Console.WriteLine("{0}: {1}", property.Name, auto);
        }
    }
}

显然你通常想先检查是否是一个吸气剂:)

答案 1 :(得分:0)

没有像“用户定义”属性那样的东西。要了解声明属性的继承层次结构中的类型,请查看PropertyInfo.DeclaringType

答案 2 :(得分:0)

如果您想知道属性是否被继承,请将PropertyInfo.DeclaringType与您正在测试的Type进行比较

答案 3 :(得分:0)

也许您想知道哪一个不是.NET Framework。

您可以调用Type.GetProperties并使用LINQ迭代找到的属性,以便了解在类中定义它们的位置,以及在框架级别中定义哪些属性。

正如其他人所说,您需要PropertyInfo.DeclaringType来了解某些属性的定义位置。

如果你的项目的任何对象都是从某个基类继承的,那么你可以这样做:

someObject.GetType().GetProperties().Where(propInfo => propInfo.DeclaringType.IsSubclassOf(typeof(ProjectBaseType))

答案 4 :(得分:0)

如果您想获取这些非继承成员,请尝试Type.GetProperties,并将BindingFlags.DeclaredOnly作为参数传递,如:

var properties  = typeof(test).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);