【问题标题】:How to determine if the property belongs to Base class or sub class dynamically in generic type using reflection?如何使用反射在泛型类型中动态确定属性是属于基类还是子类?
【发布时间】:2018-02-22 01:23:10
【问题描述】:

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

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 中提到的子类还是基类,但这也无济于事。

【问题讨论】:

标签: c# .net generics inheritance reflection


【解决方案1】:

你可以试试这个

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

【讨论】:

  • 谢谢你的工作就像一个魅力:) 你节省了我很多时间。
【解决方案2】:

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

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

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

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

【讨论】:

  • 谢谢,但它没有返回任何属性。我是不是错过了什么。你检查这个demo我使用你的代码。
  • @KaranDesai,你需要包含我上面展示的三个 BindingFlags。当您调用 GetProperties 而不指定任何 BindingFlags 时,它使用 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance。因此,您可能希望将BindingFlags.Static 包含在列表中;它仅取决于您要检索的内容,这也是我提供 BindingFlags 文档链接的原因。
  • 感谢您的澄清。 DeclaredOnly 的描述让我很困惑。当我添加所有三个标志时,这也有效。 +1
【解决方案3】:

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

var type = typeof(T);

var nameOfBaseType = "Object";

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

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

【讨论】:

  • 谢谢,但我不想要基类属性名称。我只想要子类属性名称。此外,一切都是动态发生的,所以我可能不会硬编码并分配 nameofBaseType 变量。
【解决方案4】:

我需要从基类中获取派生类名称和属性,但对基类一无所知...

基于最佳答案,我使用了以下内容...希望对其他人有所帮助!

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

【讨论】:

    猜你喜欢
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多