2

How to execute certain part of code before/after return was called. For example return may be called multiple times in a method therefore I wish not to copy paste same lines before return.

I might be wrong but some people told me that try block makes code run slow or so and my method is being called over 1000 times therefore even though this task could be accomplished with try/finally block I would like to avoid it.

Example:

void method()
{
 MyObject activator = new ...
 AnotherObject something = new ...
 SomethingElse asdf = new ...
 // some other variables 
 if(..)
    // Deactivate activator, close things, confirm user exited
    // Do some post calculations
   return;
 if(..)
    // Deactivate activator, close things, confirm user exited
    // Do some post calculations
   return;
 if(..)
    // Deactivate activator, close things, confirm user exited
    // Do some post calculations
  return;
}

Now I need to execute same code before or after every return. I the code I need to use variables defined at top in the method that's why I cannot outsource. How to do this? Is there a way at all? I apologize in case of a duplicate.

dev hedgehog
  • 8,698
  • 3
  • 28
  • 55
  • Use `else if` without returns? – James Sep 11 '14 at 07:50
  • 1
    `try` block is quite efficient, providing that no exception is thrown (which results into slow stack tracing) – Dmitry Bychenko Sep 11 '14 at 07:50
  • Can you give a more complete example of what you are trying to achieve? What code needs to be called? – dav_i Sep 11 '14 at 07:51
  • If you are not willing to use `try/final` blocks, are you willing to use a `goto`-`label` combination? http://msdn.microsoft.com/en-us/library/13940fs2.aspx – Sander Sep 11 '14 at 07:51
  • @judgeja I thought about that too but I cannot change that requirement. – dev hedgehog Sep 11 '14 at 07:51
  • *"some people told me that try block makes code run slow"*. Based on what? A `try-catch` will prevent certain optimizations of your code, but will definitely by itself will not make your code slow. Have you tested it with/without? – Yuval Itzchakov Sep 11 '14 at 07:51
  • Try catch blocks apparently have no cost if they aren't handling an exception... http://stackoverflow.com/questions/3480124/performance-cost-of-a-try-catch-block – James Sep 11 '14 at 07:52
  • I'm confused, mean you want there to only be one return from your method? (just make it the last line of your method for this) or you need to access the second two if statements before returning? (see first point) – Sayse Sep 11 '14 at 07:52
  • I provided another example – dev hedgehog Sep 11 '14 at 07:55
  • @YuvalItzchakov It is just what I have heard, I might be wrong and I also do not know base on what. If you know better please teach me so. – dev hedgehog Sep 11 '14 at 07:56

3 Answers3

5

I'm not exactly clear on what you are trying to achieve but based on your post, you could use the dreaded goto statement!

public void Test()
{
    if (...)
        goto Finish;
    if (...)
        goto Finish;
    
    Finish:
    DoSomething();  
}

Based on your update's I'd definitely consider using a finally block:

void Main()
{
    try 
    {
     MyObject activator = new ...
     AnotherObject db_connection = new ...
     Proxy p = new ...
     // some other variables 
     if(..)
      return;
     if (...)
        return;
    }
    finally
    {
        // Deactivate activator, close db connection, call a webservice to confirm user exited
        // Do some post calculations
    }
}

Efficiency of try-finally

The try-finally pattern is extremely efficient. Consider the following code:

try
{
    Console.WriteLine("Foo");
}
finally
{
    Console.WriteLine("Bar");
}

This compiles to the following IL:

IL_0000:  ldstr       "Foo"
IL_0005:  call        System.Console.WriteLine
IL_000A:  leave.s     IL_0017
IL_000C:  ldstr       "Bar"
IL_0011:  call        System.Console.WriteLine
IL_0016:  endfinally  

Which in English is:

Load the string "Foo" and call WriteLine with it. We have a finally statement so when we've called that, go to location IL_0017 - the end of the method. Load string "Bar" and call WriteLine with it. The finally has finished now so we can continue to the location we defined before the finally block.

Community
  • 1
  • 1
dav_i
  • 27,509
  • 17
  • 104
  • 136
1

Maybe consider a try-finally construction. It is used for code paths where an exception can be thrown, but cleanup still has to happen always (even after an exception is thrown).

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

void method() {
     MyObject activator = new ...
     AnotherObject db_connection = new ...
     Proxy p = new ...
     try{
         // some other variables 
         if(..)
            // Do some post calculations
         if(..)
            // Do some post calculations
         if(..)
            // Do some post calculations
    }
    finally{
        // Deactivate activator, close db connection, call a webservice to confirm user exited
    }
      return;
}

// UPDATE

I wonder if you shouldn't redesign your application or code path if a try/finally is so performance heavy that it breaks your application. You seem to open and close a connection a 1000+ times in very short time. Is this a connection to a 1000+ DBs, or a 1000+ users connecting to a DB? Why not keep it open? Can you share some additional details on the use-case?

bastijn
  • 5,841
  • 5
  • 27
  • 43
0

I am not yet clear what you are looking for. But What I understood is. You want to Instantiate few objects with values and once done you want to dispose/disconnect them before you move out of the method.

So here is what I have tried with console application, you can dispose/disconnect your values in Disposed() method.

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Callmethod();
            Console.WriteLine("--------------------");
            Console.WriteLine("Disposed");
            Console.ReadKey();
        }

        private static string Callmethod()
        {
            using (MyObject obj = new MyObject())
            {
                Console.WriteLine(obj.strTest);
                Console.WriteLine("..");
                Console.WriteLine("..");
                Console.WriteLine("..");
                Console.WriteLine("..");
                return obj.strTest;
            }
        }
    }
    public class MyObject : IDisposable
    {
        public string strTest { get; set; }
        public MyObject()
        {
            strTest = "Intantiated";
        }

        public void Dispose()
        {
            Console.WriteLine("Disposing");
        }
    }
}

Hope this helps

Sandip
  • 981
  • 1
  • 6
  • 22