20
public class Foo
{
    private Bar FooBar {get;set;}

    private class Bar
    {
        private string Str {get;set;}
        public Bar() {Str = "some value";}
    }
 }

If I've got something like the above and I have a reference to Foo, how can I use reflection to get the value Str out Foo's FooBar? I know there's no actual reason to ever do something like this (or very very few ways), but I figure there has to be a way to do it and I can't figure out how to accomplish it.

edited because I asked the wrong question in the body that differs from the correct question in the title

David L
  • 32,885
  • 8
  • 62
  • 93
claudekennilol
  • 992
  • 2
  • 13
  • 26
  • 1
    What have you tried? A bit of google and some trial and error and you should have this done in no time. – Charles Mager Jun 10 '15 at 17:26
  • possible duplicate of [Access private fields](http://stackoverflow.com/questions/10862747/access-private-fields) – Emz Jun 10 '15 at 17:26
  • 1
    This really isn't a difficult thing to do, its not all that dissimilar from public ones, you just need to specify different `BindingFlags`. – Ron Beyer Jun 10 '15 at 17:27
  • My question is different in that every example I've found here only goes one level deep. I typed out the wrong question in the body of the question that differed from the question correctly asked in the title – claudekennilol Jun 10 '15 at 18:09

2 Answers2

36

You can use the GetProperty method along with the NonPublic and Instance binding flags.

Assuming you have an instance of Foo, f:

PropertyInfo prop =
    typeof(Foo).GetProperty("FooBar", BindingFlags.NonPublic | BindingFlags.Instance);

MethodInfo getter = prop.GetGetMethod(nonPublic: true);
object bar = getter.Invoke(f, null);

Update:

If you want to access the Str property, just do the same thing on the bar object that's retrieved:

PropertyInfo strProperty = 
    bar.GetType().GetProperty("Str", BindingFlags.NonPublic | BindingFlags.Instance);

MethodInfo strGetter = strProperty.GetGetMethod(nonPublic: true);

string val = (string)strGetter.Invoke(bar, null);
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • 1
    I misspoke in the body of the question and typed out a question different than the one posed in the title. I'm not trying to Foo's FooBar, I'm trying to get Foo's FooBar's Str. – claudekennilol Jun 10 '15 at 18:12
  • Thanks. I thought I'd tried that but must've had a typo in there somewhere. It really was as easy as it should have been. – claudekennilol Jun 10 '15 at 18:24
  • If you have an instance of `var f = new Foo()`, after `object bar = getter.Invoke(f, null);` bar will still be null and `bar.GetType()...` will fail with NullReferenceException, correct? Did I missed something? – Marcelo Scofano Diniz Dec 01 '21 at 01:02
8

There is a way to slightly simplify Andrew's answer.

Replace the calls to GetGetMethod() + Invoke() with a single call to GetValue() :

PropertyInfo barGetter =
    typeof(Foo).GetProperty("FooBar", BindingFlags.NonPublic | BindingFlags.Instance);
object bar = barGetter.GetValue(f);

PropertyInfo strGetter =
    bar.GetType().GetProperty("Str", BindingFlags.NonPublic | BindingFlags.Instance);
string val = (string)strGetter.GetValue(bar);

I did some testing, and I didn't find a difference, then I found this answer, which says that GetValue() calls GetGetMethod() with error checking, so there is no practical difference (unless you worry about performance, but when using Reflection I guess that you won't).

Arkane
  • 352
  • 4
  • 10