Предполагая следующую гипотетическую иерархию наследования:
public interface IA
{
int ID { get; set; }
}
public interface IB : IA
{
string Name { get; set; }
}
Используя отражение и сделав следующий вызов:
typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)
даст только свойства интерфейса 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)
вернет массив PropertyInfo
объектов для " ID
" и " Name
".
Есть ли простой способ найти все свойства в иерархии наследования для интерфейсов, как в первом примере?
c#
.net
reflection
sduplooy
источник
источник
Stack<Type>
вместоQueue<>
. В стеке предки поддерживают такой порядок, чтоinterface IFoo : IBar, IBaz
гдеIBar : IBubble
и 'IBaz: IFlubber, the order of reflection becomes:
IBar,
IBubble,
IBaz,
IFlubber,
IFoo`.GetProperties
. Вы используетеGetInterfaces
в своем начальном типе, который вернет сплющенный список всех интерфейсов, и просто выполните егоGetProperties
для каждого интерфейса. Нет необходимости в рекурсии. В интерфейсах нет наследования или базовых типов.Type.GetInterfaces
возвращает уплощенную иерархию, поэтому нет необходимости в рекурсивном спуске.Весь метод может быть написан намного более кратко, используя LINQ:
источник
GetValue
извлеченноеPropertyInfo
, передав свой экземпляр (значение свойства которого нужно получить) в качестве параметра. Пример:var list = new[] { 'a', 'b', 'c' }; var count = typeof(IList).GetPublicProperties().First(i => i.Name == "Count").GetValue(list);
← вернет 3, даже еслиCount
он определен внутриICollection
, notIList
.GetInterfaces
не требуется, еслиtype
это класс, потому что конкретный класс ДОЛЖЕН реализовывать все свойства, которые определены во всех интерфейсах вниз по цепочке наследования. ИспользованиеGetInterfaces
в этом сценарии приведет к дублированию ВСЕХ свойств.Иерархии интерфейсов - это проблема - они на самом деле не «наследуются» как таковые, поскольку у вас может быть несколько «родителей» (из-за отсутствия лучшего термина).
«Сглаживание» (опять же, не совсем правильный термин) иерархии может включать проверку всех интерфейсов, которые интерфейс реализует, и работу оттуда ...
источник
Точно такая же проблема имеет обходной путь, описанный здесь .
FlattenHierarchy не работает, кстати. (только для статических переменных. говорит об этом в intellisense)
Обходной путь. Остерегайтесь дубликатов.
источник
Отвечая на @douglas и @ user3524983, следующий ответ должен ответить на вопрос OP:
или для отдельного объекта:
Хорошо, в следующий раз я отлажу перед публикацией, а не после :-)
источник
это сработало для меня красиво и лаконично в настраиваемом связывателе модели MVC. Тем не менее, должна быть возможность экстраполировать на любой сценарий отражения. По-прежнему воняет, что это слишком
источник