4
var pt = Type.GetType("<Program>$");
var m = pt.GetMethod("<Main>$", BindingFlags.Static);
// m is null

Okay, I grab the Program class, this works fine. But when I go to grab the Main method, system cannot find it, and it's not in pt.GetMembers() either. What's going on?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166
  • 1
    Currently you haven't specified `BindingFlags.Public` or `BindingFlags.NonPublic`. Likewise `GetMembers()` will only return you public members unless you specify that you want non-public ones too... have you tried specifying that? – Jon Skeet Nov 23 '20 at 10:51
  • I made a similar question yesterday and the answers there are good so I want to link here: https://stackoverflow.com/questions/65164165/how-do-i-get-the-reflection-typeinfo-of-a-c-sharp-9-program-that-use-top-level-s – Luke Vo Dec 07 '20 at 01:19

2 Answers2

5

You just need to specify that you want to see non-public members:

using System;
using System.Reflection;

var pt = Type.GetType("<Program>$");
var m = pt.GetMethod("<Main>$", BindingFlags.Static | BindingFlags.NonPublic);
Console.WriteLine(m); // Prints Void <Main>$(System.String[])

Likewise using GetMembers, you need to specify you want public and non-public members:

using System;
using System.Reflection;

var pt = Type.GetType("<Program>$");
var flags =
    BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.Static;
foreach (var member in pt.GetMembers(flags))
{
    Console.WriteLine(member);
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Since the generational patterns were changed (as it was mentioned in the original feature spec, names for generated class and method are implementation depended), now the generated class name is Program which is now covered in the spec:

The type is named "Program", so can be referenced by name from source code. It is a partial type, so a type named "Program" in source code must also be declared as partial.

But the name for the synthesized Main method is (still) implementation depended:

But the method name "Main" is used only for illustration purposes, the actual name used by the compiler is implementation dependent and the method cannot be referenced by name from source code.

There is another thing to note - this method is an entry point of the assembly:

The method is designated as the entry point of the program. Explicitly declared methods that by convention could be considered as an entry point candidates are ignored.

So you can access it via Assembly.EntryPoint property (so no need to rely on the name):

var assemblyEntryPoint = typeof(Program).Assembly.EntryPoint;
Guru Stron
  • 102,774
  • 10
  • 95
  • 132