关于c#:返回之前或之前触发代码


Trigger code after or before return

如何在调用返回之前/之后执行代码的某些部分。例如,一个方法中可以多次调用返回,因此我不希望在返回之前复制粘贴相同的行。

我可能是错的,但有人告诉我,try块会使代码运行缓慢,而且我的方法被调用了1000多次,因此即使这个任务可以用try/finally块完成,我还是想避免它。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
}

现在我需要在每次返回之前或之后执行相同的代码。我需要使用在方法顶部定义的变量的代码,这就是我不能外包的原因。怎么做?有什么办法吗?如有复制品,我深表歉意。


我不太清楚你想达到什么目标,但根据你的帖子,你可以使用可怕的goto声明!

1
2
3
4
5
6
7
8
9
10
public void Test()
{
    if (...)
        goto Finish;
    if (...)
        goto Finish;

    Finish:
    DoSomething();  
}

根据您的更新,我肯定会考虑使用finally块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
    }
}

最终的尝试效率

最终尝试模式非常有效。考虑以下代码:

1
2
3
4
5
6
7
8
try
{
    Console.WriteLine("Foo");
}
finally
{
    Console.WriteLine("Bar");
}

这将编译为以下IL:

1
2
3
4
5
6
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

英语中是:

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.


也许可以考虑一个尝试性的最终建设。它用于可以抛出异常的代码路径,但清理仍然必须始终进行(即使在抛出异常之后)。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

//更新

我想知道,如果一个try/finally的性能太重,以致于它破坏了您的应用程序,您是否不应该重新设计您的应用程序或代码路径。您似乎在很短的时间内打开和关闭了1000多次连接。这是连接到1000+DBS,还是连接到1000+DBS的用户?为什么不把它打开?你能分享一些关于用例的额外细节吗?


我还不清楚你在找什么。但我理解的是。您希望用值实例化几个对象,一旦完成,您希望在移出方法之前释放/断开它们。

下面是我对控制台应用程序的尝试,您可以在Disposed()方法中释放/断开您的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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");
        }
    }
}

希望这有帮助