一尘不染

GetProperties()返回接口继承层次结构的所有属性

c#

假设以下假设继承层次结构:

public interface IA
{
  int ID { get; set; }
}

public interface IB : IA
{
  string Name { get; set; }
}

使用反射并进行以下调用:

typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)

只会产生interface的属性IB,即“ Name”。

如果我们要对以下代码进行类似的测试,

public abstract class A
{
  public int ID { get; set; }
}

public class B : A
{
  public string Name { get; set; }
}

该调用typeof(B).GetProperties(BindingFlags.Public | BindingFlags.Instance)将返回PropertyInfoID”和“ Name” 的对象数组。

是否像第一个示例一样,有一种简单的方法可以在接口的继承层次结构中找到所有属性?


阅读 393

收藏
2020-05-19

共1个答案

一尘不染

我已经将@Marc Gravel的示例代码调整为一个有用的扩展方法,该方法封装了类和接口。我还首先添加了接口属性,我认为这是预期的行为。

public static PropertyInfo[] GetPublicProperties(this Type type)
{
    if (type.IsInterface)
    {
        var propertyInfos = new List<PropertyInfo>();

        var considered = new List<Type>();
        var queue = new Queue<Type>();
        considered.Add(type);
        queue.Enqueue(type);
        while (queue.Count > 0)
        {
            var subType = queue.Dequeue();
            foreach (var subInterface in subType.GetInterfaces())
            {
                if (considered.Contains(subInterface)) continue;

                considered.Add(subInterface);
                queue.Enqueue(subInterface);
            }

            var typeProperties = subType.GetProperties(
                BindingFlags.FlattenHierarchy 
                | BindingFlags.Public 
                | BindingFlags.Instance);

            var newPropertyInfos = typeProperties
                .Where(x => !propertyInfos.Contains(x));

            propertyInfos.InsertRange(0, newPropertyInfos);
        }

        return propertyInfos.ToArray();
    }

    return type.GetProperties(BindingFlags.FlattenHierarchy
        | BindingFlags.Public | BindingFlags.Instance);
}
2020-05-19