15

I have following two classes (models), one is base class and other is sub class:

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

public class ChildClass: BaseClass    
{    
     public string ChildProperty{get;set;}    
}

In application I am calling ChildClass dynamically using generics

List<string> propertyNames=new List<string>();
foreach (PropertyInfo info in typeof(T).GetProperties())
{
      propertyNames.Add(info.Name);
}

Here, in propertyNames list, I am getting property for BaseClass as well. I want only those properties which are in child class. Is this possible?

What I tried?

  1. Tried excluding it as mentioned in this question
  2. Tried determining whether the class is sub class or base class as mentioned here but that does not help either.
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Karan Desai
  • 3,012
  • 5
  • 32
  • 66
  • 3
    Nice q. I think you mean using Reflection though and not Generics? – StuartLC Sep 13 '17 at 11:01
  • 1
    https://stackoverflow.com/questions/12667219/reflection-exclude-all-attributes-from-base-class-and-specific-attribute-from-al – Ric Sep 13 '17 at 11:02

4 Answers4

14

You can try this

foreach (PropertyInfo info in typeof(T).GetProperties()
        .Where(x=>x.DeclaringType == typeof(T))) // filtering by declaring type
{
    propertyNames.Add(info.Name);
}
tym32167
  • 4,741
  • 2
  • 28
  • 32
4

...I want only those properties which are in child class. Is this possible?

You need to use the GetProperties overload that takes a BindingFlags argument and include the BindingFlags.DeclaredOnly flag.

PropertyInfo[] infos = typeof(ChildClass).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

DeclaredOnly: Specifies that only members declared at the level of the supplied type's hierarchy should be considered. Inherited members are not considered.

TnTinMn
  • 11,522
  • 3
  • 18
  • 39
  • Thanks, but it does not return me any properties. Am i missing something. You check this [demo](http://rextester.com/MNAHMY33063) I made using your code. – Karan Desai Sep 14 '17 at 02:53
  • 1
    @KaranDesai, you need to include the three BindingFlags I showed above. When you call `GetProperties` without specifying any BindingFlags, it uses `BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance`. So you may want to include `BindingFlags.Static` to the list; it just depends what you want to retrieve and is the reason that I provided the link to the BindingFlags documentation. – TnTinMn Sep 14 '17 at 03:02
  • Thanks for clarifying. DeclaredOnly's description confused me. This worked too when I added all three flags. +1 – Karan Desai Sep 14 '17 at 03:22
2

Using a simple loop to get the base class property names

var type = typeof(T);

var nameOfBaseType = "Object";

while (type.BaseType.Name != nameOfBaseType)
{
    type = type.BaseType;
}

propertyNames.AddRange(type.GetProperties().Select(x => x.Name))
qwertydog
  • 121
  • 5
  • Thanks, but I don't want base class property names. I want only child class property names. Also, everything happens dynamically so I might not hardcode and assign `nameofBaseType` variable. – Karan Desai Sep 14 '17 at 02:55
0

I needed to get from the base class the derived class name and properties but nothing about the base class...

Based on the top answer I used the following... Hopefully it helps someone else!

public abstract class StorageObject
{
    protected readonly string TableName;
    protected readonly string[] ColumnNames;

    protected StorageObject()
    {
        TableName = GetType().Name;

        ColumnNames = GetType().GetProperties().Where(x => x.DeclaringType == GetType())
            .Select(x => x.Name)
            .ToArray();
    }
}

public class Symbol : StorageObject
{
    public string Name { get; private set; }
    public bool MarginEnabled { get; private set; }
    public bool SpotEnabled { get; private set; }
    public Symbol(ICommonSymbol symbol)
    {
        Name = symbol.CommonName;
        
        if (symbol is BitfinexSymbolDetails bsd)
        {
            MarginEnabled = bsd.Margin;
        }

        if (symbol is BinanceSymbol bs)
        {
            SpotEnabled = bs.IsSpotTradingAllowed;
            MarginEnabled = bs.IsMarginTradingAllowed;
        }
        
    }
}
NotoriousPyro
  • 526
  • 3
  • 16