Why are members of a legacy interface inaccessible via reflection?

When reflected by interface type, I get only members of a certain type, and not inherited members.

In this simplified example, the program prints only "Name" and not "ItemNumber", "Name", as I expected:

using System; public interface IBasicItem { string ItemNumber { get; set; } } public interface IItem : IBasicItem { string Name { get; set; } } class Program { static void Main(string[] args) { var type = typeof (IItem); foreach (var prop in type.GetProperties()) Console.WriteLine(prop.Name); } } 

What is the reason for this? When I inherit the base interface, I say that any of the implementations of my interface must also implement inherited members. In other words, IItem is an IBasicItem. So why doesn't the inherited member appear by reflection?

+4
source share
4 answers

I think this is exactly what Phil Haack was just blogging about.

From the ECMA-335 Common Language Infrastructure Specification:

8.9.11. Type of interface. Interface types may require the implementation of one or more other interfaces. Any type that implements interface type support should also support any of the required interfaces defined by that interface. This differs from object type inheritance in two ways:

  • Object types form a single inheritance tree; interface types no.
  • Object type inheritance determines how implementations are inherited; There are no required interfaces, because interfaces do not define an implementation. The required interfaces specify additional contracts that the type of implementation object should support.

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

Link to: http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx

+10
source

A good way to think about this is that interfaces do not have "inheritance" just like classes do. Inheritance implies that it is a “kind of” relationship, but the inheritance interface actually implies that “it is required to provide this service”.

when we talk

 interface IEnumerator<T> : IDisposable 

what we are saying is not so much “sequence enumerators are kind of disposable things” as “if you provide an enumerator service, then you must also provide an“ disposal ”service.

Does that make more sense now?

+6
source

This is because you work with interfaces. Interfaces do not receive the same inheritance structure as classes.

If you have a class that implements these interfaces, you will see the correct chain (if you use "BindingFlags.FlattenHierarchy").

Try creating a class that implements a lower level interface, and you should see what you are looking for.

+1
source

This is because you are not requesting the information you want to know. In other words, since your inherited properties have a different meaning than the properties you get from interfaces, you need to access them differently.

Therefore, you can access through reflection as follows:

 foreach ( var iface in type.GetInterfaces() ) { foreach ( var prop in iface.GetProperties() ) { Console.WriteLine( iface.Name +"-"+ prop.Name ); } } 

Since class inheritance differs from interface conformance, it is logical to access them in different ways.

+1
source

All Articles