2011-01-27 3 views
1

Как я могу теперь получить список, полученный с помощью 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); 
    } 
+2

пользователь определил? вы имеете в виду не наследуемые или не переопределенные? –

+0

Я попробую уточнить, что мне нужно –

+0

Ваше обновление все еще не очень ясно. Тем не менее, некоторые догадки: вы ищете разумный способ определить, имеет ли свойство тип, относящийся к набору некоторых конкретных типов *, чтобы решить в 'GetFullNameScalarProperties', следует ли переходить к типу конкретного объекта и проверить его свойства. Правильно? –

ответ

0

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

2

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

Полезно знать, но я считаю, что речь идет не о автоинсталлированных аксессуарах. –

+0

@Matias: Это было самое близкое, что я мог догадаться, основываясь на отсутствии информации в вопросе. Это полностью * непонятно, что такое OP. –

+0

Абсолютно согласился :) Это просто комментарий! –

0

Если вы хотите Findout ли не наследуется свойство сравнить PropertyInfo.DeclaringType на вас Тип тестируют

0

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

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

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

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

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

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

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

А что, если наследование имеет более одного уровня? : D –

Смежные вопросы