25

Because of this issue here, I'm trying to write a custom JsonConverter that handles cases where you subclass a list or a collection, then add extra properties to it. As such, one approach would be to ignore all base-class properties and only serialize those in the defined class. (Technically this won't work because if you subclass that subclass you break the serialization, but it did make me wonder...)

Is it possible via reflection (well I know the answer is 'yes' because Reflector does exactly that, but I don't know how) to get only the members that are defined on the class itself as opposed to those that were inherited? For instance...

public class MyBaseClass
{
    public string BaseProp1 { get; set; }
    public string BaseProp2 { get; set; }
}

public class MySubClass : MyBaseClass
{
    public string SubProp1 { get; set; }
    public string SubProp2 { get; set; }
}

In this case, I want to reflect on MySubClass and only get SubProp1 and SubProp2 while ignoring BaseProp1 and BaseProp2. So can that be how is that done?

M

Community
  • 1
  • 1
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286

5 Answers5

38

While calling GetMembers() method to get the members of the Type, you can specify DeclaredOnly in binding flag.

fat
  • 6,435
  • 5
  • 44
  • 70
Ankur
  • 33,367
  • 2
  • 46
  • 72
12

You have to select all members in MySubClass and keep only those where DeclaringType == MySubClass.

With LINQ, something like that (overkill) :

MemberInfo[] notInherited = GetType("MySubClass").GetMembers().Where(m => m.DeclaringType == GetType("MySubClass"));

Or with GetMembers() overload :

MemberInfo[] notInherited = GetType("MySubClass").GetMembers(BindingFlags.DeclaredOnly);
user703016
  • 37,307
  • 8
  • 87
  • 112
5

A lot of reflection functions accept a parameter of type BindingFlags. This enumeration includes a value DeclaredOnly:

Specifies that only members declared at the level of the supplied type's hierarchy should be considered. Inherited members are not considered.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
3

MemberInfo.DeclaringType should do what you need. To get members directly defined in type X filter the members by DeclaringType == typeof(X).

Richard
  • 106,783
  • 21
  • 203
  • 265
  • Thx this is what i needed. I was using BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; but still somehow the inherited Object methods were coming through until i added your fix. I then noticed it wasn't the first fix of this nature i was using. To skip the get_XXX set_XXX property accessor methods i would if (MethodInfo.SpecialName) continue; – FocusedWolf Mar 05 '18 at 16:40
0

Just use this Flags :

var eFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly;
X.GetMethods(eFlags)