5

I have the following code where I'm printing values before the Main() method gets called by using a static constructor. How can I print another value after Main() has returned, without modifying the Main() method?

I want output like:

1st 
2nd 
3rd

The "base" code I use:

class Myclass
{        
    static void Main(string[] args)
    {
        Console.WriteLine("2nd");
    }              
}  

I added a static constructor to Myclass for displaying "1st"

class Myclass
{     
static Myclass() { Console.WriteLine("1st"); }   //it will print 1st 
    static void Main(string[] args)
    {
        Console.WriteLine("2nd"); // it will print 2nd
    }              
}

Now What i need to do to is to print 3rd without modifying the Main() method. How do I do that, if it is at all possible?

Anders Abel
  • 64,109
  • 15
  • 143
  • 213
Neo
  • 13,482
  • 47
  • 173
  • 339

4 Answers4

6

Continuing on your same thought with the Static constructor, you can use the AppDomain.ProcessExit Event leaving Main() untouched.

class Myclass
    {
        // will print 1st also sets up Event Handler
        static Myclass()
        {
            Console.WriteLine("1st");
            AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("2nd"); // it will print 2nd
        }

        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            Console.WriteLine("3rd");
        }
    }
Richard
  • 100,436
  • 21
  • 189
  • 251
nageeb
  • 1,974
  • 1
  • 11
  • 25
5

There are a couple of events you can attach to, to catch the Application's Exit events:

.NET Console Application Exit Event

But I am wondering what you are trying to achieve here? Are you sure you can't change your Main method? If not, why?

Can't you separate out the method body of Main into another method, and make your Main look like this:

class Myclass
{     
static Myclass() 
    static void Main(string[] args)
    {
        Console.WriteLine("1st");
        Process(args);
        Console.WriteLine("3rd");
    }  

    static void Process(string[] args) {
        Console.WriteLine("2nd"); // it will print 2nd
    }
}
Community
  • 1
  • 1
Erik A. Brandstadmoen
  • 9,864
  • 2
  • 34
  • 52
3

You can't in C#. In other languages such as C++ it is possible to do this in a destructor of a static or global object, but finalizers in C# are non-deterministic. They may not even be called at all if the object isn't garbage collected before the process is ended.

Anders Abel
  • 64,109
  • 15
  • 143
  • 213
  • Even then, the main method is static - no object destructor is called. As such, nothing works here- the class is only unloaded when the appdomain unloads. – TomTom Aug 09 '11 at 07:00
3

Add another class with a static Main suitable as a program entry point. In this call Myclass.Main:

class MyOtherClass {
  static void Main(string[] args) {
    Console.WriteLine("1st");
    Myclass.Main(args);
    Console.WriteLine("3rd");
  }
}

and then change the build options to select MyOtherClass as the program entry point. In VS this is done in Project Properties | Application | Start up object. With the command line use the /main:typename option to `csc.exe.

Richard
  • 100,436
  • 21
  • 189
  • 251
  • +1 Probably the best result. Also technically legal in the parameters given - redirecting the main method is a change in the proejct settings (entry point), not the main method itself, so it stays within the parameters asked for. – TomTom Aug 09 '11 at 07:01
  • @Ashish: One can only override virtual methods; `Main` is static so cannot be virtual and therefore cannot be overridden. – Richard Aug 09 '11 at 07:26