views:

51

answers:

2

my problem is that TypeDescriptor doesn't return members from inherited interfaces, is this how it is supposed to be working ? or is it a bug ?

 [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; }
        }
    }
+1  A: 

You are right. I think it is a bug since it works for inherited properties on classes!

Aliostad
@Aliostad what's the BindingFlags.Instance for ?
Omu
Means it is not static. It will not work if you do not include it.
Aliostad
@Aliostad typeof(IFoo).GetProperties(BindingFlags.Instance | BindingFlags.Public).Length also returns 1
Omu
You are right. I think it is a bug.
Aliostad
+6  A: 

This isn't a bug. From the ECMA CLI specification:

8.9.11 Interface type derivation

Interface types can require the implementation of one or more other interfaces. Any type that implements support for an interface type shall also implement support for any required interfaces specified by that interface. This is different from object type inheritance in two ways:

  • Object types form a single inheritance tree; interface types do not.
  • Object type inheritance specifies how implementations are inherited; required interfaces do not, since interfaces do not define implementation. Required interfaces specify additional contracts that an implementing object type shall support.

To highlight the last difference, consider an interface, IFoo, that has a single method. An interface, IBar, which derives from it, is requiring that any object type that supports IBar also support IFoo. It does not say anything about which methods IBar itself will have.

8.10 Member inheritance

Only object types can inherit implementations, hence only object types can inherit members (see §8.9.8). While interface types can be derived from other interface types, they only "inherit" the requirement to implement method contracts, never fields or method implementations.

Edit...

If you want to get the properties of an interface, including those of its ancestors, then you could do something like this:

var properties = typeof(IFoo)
                     .GetProperties()
                     .Union(typeof(IFoo)
                                .GetInterfaces()
                                .SelectMany(t => t.GetProperties()));
LukeH
In support of this answer, Reflectoring the implementation shows (I think) that `GetProperties` *does* walk up the `.BaseType` tree of the type being examined - but `typeof(IFoo).BaseType` is null, so the walk stops straightaway.
AakashM
@LukeH @AakashM do you know hot to get all the properties of IFoo ?
Omu