2014-01-16 5 views
0

Мне нужно проанализировать мой объект и показать некоторые его свойства в списке. У моего объекта есть некоторые свойства, которые исходят из базового класса «ObjectBaseClass», эти свойства не должны отображаться в моем списке.Как получить класс владельца объекта в C#

Как я могу знать, что свойство принадлежит базовому классу или нет?

i.e У меня есть интерфейс IDisposableExtended, этот интерфейс будет реализован в моем классе объектов. Но в моем списке я не хочу показывать эти два свойства «Одноразовые» и «Disposed». Как я могу их фильтровать?

public interface IDisposableExtended : IDisposable 
{ 
    bool Disposable { get; } 
    bool Disposed { get; } 
} 

Большое спасибо!

p.s Свойства могут исходить из базового класса (уровень 1), базовый класс (уровень 1) также может иметь некоторые свойства из своего базового класса (уровень 2). Это так, когда я использую GetProperties (flags), который содержит BindingFlags.DeclaredOnly, все свойства, полученные из базовых классов (уровень 1 и уровень 2), будут отфильтрованы? Могу ли я просто фильтровать уровень 1-го уровня или уровень 2? Это означает, что я хочу сначала получить все свойства и затем фильтровать в соответствии с их базовым классом вручную. Затем я могу контролировать их, чтобы показать свойства, которые мне нужны.

ответ

0

Вы должны использовать перегрузку метода Type.GetProperty(String, BindingFlags) и включить BindingFlags.DeclaredOnly, чтобы ограничить поиск членами, которые не унаследованы.

Подробнее здесь: http://msdn.microsoft.com/en-us/library/kz0a8sxy(v=vs.110).aspx

В ответ на замечание (хотя я не уверен, если я правильно понимаю). Вот быстрая программа, которая пересечет иерархию типов и отобразит свойства, объявленные самим типом, за исключением унаследованных на каждом уровне.

namespace ConsoleApplication1 
{ 
    class ClassA 
    { 
     public string ClassAProp { get; set; } 
    } 

    class ClassB : ClassA 
    { 
     public string ClassBProp { get; set; } 
    } 

    class ClassC : ClassB 
    { 
     public string ClassCProp { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var c = new ClassC(); 
      var t = c.GetType(); 
      while (t.BaseType != null) 
      { 
       var cProps = t.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); 
       foreach (var p in cProps) 
       { 
        Console.WriteLine("{0} defines {1}", t.Name, p.Name); 
       } 
       t = t.BaseType; 
      } 
      Console.ReadLine(); 
     } 
    } 
} 

Таким образом, вы можете увидеть, возвращает «» BindingFlags.DeclaredOnly только свойства, объявленные в классе. Надеюсь, это поможет достичь того, что вы ищете.

Примечание:Type.BaseType будет пустым для object, так как это тип корня. Если вы хотите, чтобы цикл останавливался на любом другом типе, вы должны быть в состоянии сказать while (t != TypeYouWantToStopAt.GetType())

+0

Свойства могут быть получены из базового класса (уровень 1), базовый класс (уровень 1) также может иметь некоторые свойства из своего базового класса (уровень 2). Является ли это тем, что когда я использую GetProperties (флаги), который содержит BindingFlags.DeclaredOnly, все свойства, полученные из базовых классов (уровень 1 и уровень 2), будут отфильтрованы? Возможно ли, что я просто фильтрую базовый уровень уровня 1 или уровень 2? Это означает, что я хочу сначала получить все свойства и затем фильтровать их в соответствии с их базовым классом вручную. Затем я могу контролировать их, чтобы показать свойства, которые мне нужны. – Ivan

1

Прежде всего, «владелец» этих свойств на самом деле является классом, а не интерфейсом. Интерфейс дает доступ к этим свойствам, но тип объявления по-прежнему является классом.

Однако свойства, которые вы наследуете, будут иметь другой тип объявления , когда вы обнаружите их через отражение. Вот LINQPad программы, которая показывает:

void Main() 
{ 
    var derivedType = typeof(Derived); 
    derivedType.GetProperties().Dump("All"); 
    derivedType.GetProperties(BindingFlags.DeclaredOnly 
     | BindingFlags.Public | BindingFlags.Instance).Dump("Declared only"); 
} 

public class Base 
{ 
    public string BaseProperty { get; set; } 
} 

public class Derived : Base 
{ 
    public string DerivedProperty { get; set; } 
} 

Обратите внимание, что если вы также реализовать интерфейс в Derived, эти методы/свойства будут также показаны при разгрузке из свойств из Derived, поскольку они объявлены по этому типу. Да, они используются для реализации интерфейса, но они также объявляются («принадлежат») типом.

+0

Свойства могут исходить из базового класса (уровень 1), базовый класс (уровень 1) также может иметь некоторые свойства из своего базового класса (уровень 2). Является ли это тем, что когда я использую GetProperties (флаги), который содержит BindingFlags.DeclaredOnly, все свойства, полученные из базовых классов (уровень 1 и уровень 2), будут отфильтрованы? Возможно ли, что я просто фильтрую базовый уровень уровня 1 или уровень 2? Это означает, что я хочу сначала получить все свойства и затем фильтровать их в соответствии с их базовым классом вручную. Затем я могу контролировать их, чтобы показать свойства, которые мне нужны. – Ivan

0

Это немного от вашего вопроса, но может дать вам представление о другом подходе к проблеме, которую вы описываете.

Вы можете объявить пользовательский атрибут, который вы используете, чтобы пометить любое свойство (или любой член на самом деле), который вы не хотите перечислить. Когда вы перечисляете свойства своего объекта, вы можете проверить его атрибуты и пропустить все, что вы отметили. Это похоже на то, как работает редактор редактора свойств .NET.

+0

Спасибо за ваш ответ. Я тоже об этом подумал. Но это слишком дорого для этого ;-) – Ivan

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