How do I get the Reflection TypeInfo of a C# 9 program that use Top-level statements?

668 Views Asked by At

Assume I have a simple script writing in C# 9 like this:

using System;
using System.IO;

// What to put in the ???
var exeFolder = Path.GetDirectoryName(typeof(???).Assembly.Location);

Before, with the full program, we can use the Main class as an "indicator" class. this and this.GetType() is not available because technically it's inside a static method. How do I get it now?


A workaround I thought of while typing the question is Assembly.GetCallingAssembly():

var exeFolder = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);

It works for my case, but I can only get the Assembly, not the TypeInfo that in which the code is running.

3

There are 3 best solutions below

0
On BEST ANSWER

I suggest starting from the method which is executing (Main):

TypeInfo result = MethodBase
  .GetCurrentMethod() // Executing method         (e.g. Main)
  .DeclaringType      // Type where it's declared (e.g. Program)
  .GetTypeInfo();    

If you want Type, not TypeInfo drop the last method:

Type result = MethodBase
  .GetCurrentMethod() // Executing method         (e.g. Main)
  .DeclaringType;     // Type where it's declared (e.g. Program)

 
1
On

You can also get the assembly using GetEntryAssembly.

Once you have the assembly that your code is in, you can get its EntryPoint, which is the compiler-generated "Main" method. You can then do DeclaringType to get the Type:

Console.WriteLine(Assembly.GetEntryAssembly().EntryPoint.DeclaringType);

The above should get the compiler-generated "Program" class even if you are not at the top level.

0
On

For C# 10 (See 4th point in the breaking changes) compiler generates Program class for top-level statements so you can use it:

Console.WriteLine(typeof(Program).FullName);

And though original (C# 9) docs state that:

Note that the names "Program" and "Main" are used only for illustrations purposes, actual names used by compiler are implementation dependent and neither the type, nor the method can be referenced by name from source code.

ASP.NET Core integration testing docs rely on this naming convention for the class.