TypeDescriptor не возвращает членов из унаследованных интерфейсов - PullRequest
4 голосов
/ 27 октября 2010

Моя проблема в том, что TypeDescriptor не возвращает членов от унаследованных интерфейсов, это так и должно работать? или это баг?

 [TestFixture]
    public class DescriptorTests
    {
        [Test]
        public void Test()
        {
                                                                    // count = 1 
            Assert.AreEqual(2, TypeDescriptor.GetProperties(typeof(IFoo)).Count);
     // it is going to fail, the Id is not going to be returned
        }

        public interface IEntity
        {
            int Id { get; set; }
        }

        public interface IFoo : IEntity
        {
            string Name { get; set; }
        }
    }

Ответы [ 2 ]

9 голосов
/ 27 октября 2010

Это не ошибка. Из спецификации ECMA CLI :

8.9.11 Вывод типа интерфейса

Типы интерфейса могут требовать реализация одного или нескольких других интерфейсы. Любой тип, который реализует поддержка типа интерфейса должна также реализовать поддержку любого требуемые интерфейсы, указанные этим интерфейс. Это отличается от Наследование типов объектов двумя способами:

  • Типы объектов образуют единое дерево наследования; типы интерфейса делают нет.
  • Наследование типа объекта указывает, как реализации наследуются; необходимых интерфейсов нет, так как интерфейсы не определяют реализация. Требуемые интерфейсы указать дополнительные контракты, которые реализующий тип объекта должен поддержка.

Чтобы выделить последнее различие, рассмотрим интерфейс, IFoo, который имеет единственный метод. Интерфейс, IBar, который вытекает из этого, является требуя, чтобы любой тип объекта, который поддерживает IBar также поддерживает IFoo. Здесь ничего не сказано о чем методы IBar сам будет иметь.

8.10 Членское наследство

Только типы объектов могут наследовать реализации, следовательно, только объект типы могут наследовать членов (см. §8.9.8). Хотя типы интерфейсов могут быть получены из других типов интерфейса, они только «наследуют» требование выполнять контракты методом, никогда поля или реализации метода.

Редактировать ...

Если вы хотите получить свойства интерфейса, включая свойства его предков, то вы можете сделать что-то вроде этого:

var properties = typeof(IFoo)
                     .GetProperties()
                     .Union(typeof(IFoo)
                                .GetInterfaces()
                                .SelectMany(t => t.GetProperties()));
1 голос
/ 27 октября 2010

Вы правы. Я думаю, что это ошибка, поскольку она работает для унаследованных свойств на классах!

...