如何使用反射确定属性是否在泛型类型中动态属于Base类或子类?

时间:2017-09-13 10:57:56

标签: c# .net generics inheritance reflection

我有两个类(模型),一个是基类,另一个是子类:

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

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

在应用程序中,我使用泛型

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

此处,在propertyNames列表中,我也获得了BaseClass的属性。我只想要那些在子类中的属性。这可能吗?

我尝试了什么?

  1. 尝试将其排除在此question
  2. 尝试确定该类是提及here的子类还是基类,但这也无济于事。

4 个答案:

答案 0 :(得分:11)

你可以试试这个

foreach (PropertyInfo info in typeof(T).GetProperties()
        .Where(x=>x.DeclaringType == typeof(T))) // filtering by declaring type
{
    propertyNames.Add(info.Name);
}

答案 1 :(得分:2)

使用简单循环获取基类属性名称

var type = typeof(T);

var nameOfBaseType = "Object";

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

propertyNames.AddRange(type.GetProperties().Select(x => x.Name))

答案 2 :(得分:2)

  

...我只想要那些属于子类的属性。这可能吗?

您需要使用带有GetProperties参数的BindingFlags重载并包含BindingFlags.DeclaredOnly标记。

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

DeclaredOnly:指定只应考虑在提供的类型层次结构级别声明的成员。不考虑继承的成员。

答案 3 :(得分:0)

我需要从基类获取派生类名称和属性,但没有关于基类的信息...

根据我使用的最佳答案...希望对其他人有帮助!

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;
        }
        
    }
}