Middle · Trace · Explicit member discovery with BindingFlags

Explain why Own is the only enumerated method while the separate inherited and private checks succeed.

Think through your answer before opening the explanation.

Runtime & concurrency

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Reflection;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
string[] names = typeof(Probe).GetMethods(flags).Select(method => method.Name).OrderBy(name => name, StringComparer.Ordinal).ToArray();
Console.WriteLine("declared:" + string.Join(",", names));
Console.WriteLine($"inherited:{typeof(Probe).GetMethod(nameof(Parent.Inherited)) is not null}");
Console.WriteLine($"private:{typeof(Probe).GetMethod("Secret", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)!.IsPrivate}");
class Parent { public void Inherited() { } }
sealed class Probe : Parent { public void Own() { } private void Secret() { } }
Reveal answer and reasoning

The output is declared:Own, inherited:True, and private:True. Public plus Instance plus DeclaredOnly selects Own from Probe. Secret is nonpublic, and Inherited belongs to Parent, so neither is part of that enumeration. The subsequent ordinary public GetMethod lookup is a different query and can find Inherited through the base relationship. The final explicit nonpublic declared-instance lookup finds Secret and reads its IsPrivate flag.

The ordinal sort makes the first report deterministic, although only one name matches in this baseline. The program does not invoke Secret, grant access to arbitrary private code, or prove every metadata member survives trimming. A common wrong trace adds Inherited to the declared list because it overlooks DeclaredOnly, or assumes private discovery must fail simply because source-level direct access is unavailable.

Each output belongs to its own query contract rather than one universal member set.

What a strong answer covers

  • DeclaredOnly excludes Parent.Inherited from the first query.
  • The inherited lookup uses different defaults.
  • The explicit private lookup reads metadata only.

Common pitfall

Conflating three differently scoped reflection queries into one result set.

Follow-up questions

  1. What changes if Probe declares a public property?
  2. What changes if another public instance method is added?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions