Glad
Glad

Reputation: 147

Reflection : Getting members from inherited interface, but not from inherited class

I believe I've got an interesting question there, since I couldn't find a clue about that during my research.

public interface IClass
{
    int i { get; set; }
}

public class A
{
    int j { get; set; }
}

public class B : A, IClass
{
    string property { get; set; }
}

I would like to know if it is possible, using Reflection, to get all the inherited members of my class B and from the inherited interface IClass, but without the property from the inherited class A.

I've tried using BindingFlags.DeclaredOnly, but this always gets all the inherited members, when I only desire to get the ones from the Interface.

Any ideas, please ?

-- Arjune

EDIT : I intend to get interface inherited properties, with a generic class T. Here is what I tried which worked, thanks to your answers :

List<PropertyInfo> properties = typeof(T).GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public).Where(x => x.DeclaringType != typeof(T).BaseType).ToList();

Besides the properties of B, this allowed me to get the properties from IClass but not the ones from class A. LINQ and the use of DeclaringType was the answer.

Upvotes: 3

Views: 1132

Answers (4)

DavidWainwright
DavidWainwright

Reputation: 2935

This should do it:

var allMembers = myType.GetMembers()
    .Union(myType.GetInterfaces()
    .SelectMany(i => i.GetMembers())

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062695

How about:

var members = type.GetMembers(flags).Concat(
    type.GetInterfaces().SelectMany(x => x.GetMembers(flags))).ToList();

(where flags is your chosen BindingFlags options, that must include DeclaredOnly)

Upvotes: 1

Philip Pittle
Philip Pittle

Reputation: 12295

If given a type T you want to get all inherited members from an interface, you can try this:

public static IEnumerable<MemberInfo> GetAllInterfaceMembers(this Type t){
     return t.GetInterfaces().SelectMany(x => x.GetMembers());
}

Upvotes: 1

Jon
Jon

Reputation: 437336

You can go about this in a number of ways, depending on your exact aim.

One idea is to get all properties normally then filter out those coming from class A using DeclaringType, e.g.

var typeOfA = typeof(A);
var notFromA = allMembers.Where(
    p => p.DeclaringType != typeOfA && !p.DeclaringType.IsSubclassOf(typeOfA));

Or of course you can simply ignore the base class completely and get only the members coming from implemented interfaces, e.g.

var members = typeof(B).GetInterfaces().SelectMany(i => i.GetMembers());

This will give you all members of B that are implementations of interface members -- not necessarily all of B's declared members, and it will include interface members that A has implemented.

In general the correct way to do this depends on the exact requirements, but I feel the question is not precise enough in its current form.

Upvotes: 1

Related Questions