Отражение всех свойств интерфейса, включая унаследованные?

У меня есть экземпляр System.Type, который представляет собой интерфейс, и я хочу получить список всех свойств этого интерфейса, включая те, которые унаследованы от базовых интерфейсов. Я в основном хочу того же поведения от интерфейсов, которые я получаю для классов.

Например, учитывая эту иерархию:

public interface IBase {
    public string BaseProperty { get; }
}
public interface ISub : IBase {
    public string SubProperty { get; }
}
public class Base : IBase {
    public string BaseProperty { get { return "Base"; } }
}
public class Sub : Base, ISub {
    public string SubProperty { get { return "Sub"; } }
}

Если я вызываю GetProperties в классе - typeof(Sub).GetProperties() - тогда я получаю как BaseProperty, так и SubProperty. Я хочу сделать то же самое с интерфейсом, но когда я попробую - typeof(ISub).GetProperties() - все, что возвращается, это SubProperty.

Я попытался передать BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy в GetProperties, так как мое понимание FlattenHierarchy заключается в том, что он должен включать членов из базовых классов, но поведение было точно таким же.

Я предположил, что могу выполнять итерацию Type.GetInterfaces() и вызывать GetProperties на каждом из них, но тогда я бы полагался на GetProperties на интерфейсе, чтобы никогда не возвращать базовые свойства (поскольку, если это когда-либо, я получаю дубликаты). Я бы предпочел не полагаться на это поведение, по крайней мере, не задокументировав его.

Как я могу:

  • Получить список всех свойств интерфейса, в том числе из его базовых интерфейсов? Или
  • По крайней мере, быть уверенным, что то, что я вижу, - это документированное поведение, на которое я могу положиться, поэтому я могу обойти его.

Ответы

Ответ 1

Ответ в виде можно найти в аннотации к странице MSDN на .NET Framework версии 3.5 на GetProperties(BindingFlags bindingFlags):

Передача BindingFlags.FlattenHierarchy к одному из методов Type.GetXXX, такие как Type.GetMembers, не будут возвращать унаследованные элементы интерфейса когда вы запрашиваете интерфейс типа.

[...]

Чтобы получить унаследованных членов, вам нужно для запроса каждого реализованного интерфейса для своих членов.

Также приведен пример кода. Этот комментарий был отправлен Microsoftie, поэтому я бы сказал, что вы можете доверять ему.