Свойство определяется пользователем? - PullRequest
1 голос
/ 27 января 2011

Как я могу теперь в списке, полученном с 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; }
    }

Итак, в рекурсивном методе я получаю свойства и создаю список с именами

банкомат, который проходит этот тест

    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 ]

2 голосов
/ 27 января 2011

Непонятно, что вы подразумеваете под «пользовательским» - пытаетесь ли вы определить разницу между автоматически реализованным свойством и тем, которое было написано от руки?Если это так, автоматически реализованное свойство будет иметь атрибут [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);
        }
    }
}

Очевидно, что обычно вы хотите проверить, является ли получателем первым:)

0 голосов
/ 27 января 2011

Если вы хотите получить эти не унаследованные члены, попробуйте Type.GetProperties и передайте BindingFlags.DeclaredOnly в качестве аргумента, например:

var properties  = typeof(test).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
0 голосов
/ 27 января 2011

Может быть, вы хотите знать, какие из них не являются .NET Framework.

Вы можете вызывать Type.GetProperties и повторять найденные свойства с помощью LINQ, чтобы узнать, где они были определены в вашем классе, а какие - на уровне платформы.

Как уже говорили другие, вам нужно PropertyInfo.DeclaringType, чтобы узнать, где определено какое-либо свойство.

Если какой-либо объект вашего проекта наследуется от некоторого базового класса, возможно, вы можете сделать это:

someObject.GetType().GetProperties().Where(propInfo => propInfo.DeclaringType.IsSubclassOf(typeof(ProjectBaseType))
0 голосов
/ 27 января 2011

Если вы хотите узнать, наследуется ли свойство, сравните PropertyInfo.DeclaringType с типом, который вы тестируете

0 голосов
/ 27 января 2011

Ничто не похоже на свойство, определяемое пользователем.Чтобы узнать, в каком типе иерархии наследования было объявлено свойство, взгляните на PropertyInfo.DeclaringType.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...