C#,像golang那样'Defer Call'吗?

时间:2016-11-19 07:49:13

标签: c# destructor

golang支持'推迟调用',当c ++时,我使用这个技巧(?)。

struct DeferCall
{
   DeferCall() {}
   ~DeferCall() { doSomeThing(); }
}

void SomeMethod()
{
    DeferCall deferCall;
    ...
}

我怎么能在c#中做到这一点?

我需要这样golang defer tutorial

3 个答案:

答案 0 :(得分:8)

最接近的语言是try-finally

try
{
    DoSomething();
}
finally
{
    DoCleanup();
}

最近的框架等效项为IDisposable + using

using (var stream = File.OpenRead("foo.txt"))
{
    // do something
}

就个人而言,defer一词让我感到困惑,因为这不是“延迟执行”(现在安排 - 稍后执行,可以通过任务实施), 但某种RAII实施。

P.S。 假设你将继续学习golang:

答案 1 :(得分:1)

否,但并非不可能 defer是一个关键字,旨在在其父函数返回时执行函数,并在到达return语句时开始执行。

由于defer的执行就像堆栈一样,因此按顺序调用延迟函数将导致相反的顺序。

package main

import (
    "fmt"
)

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")

    if num := 2; num == 2 {
        defer fmt.Println("4")
        return
    }
    defer fmt.Println("5")
}

// 4
// 3
// 2
// 1

https://play.golang.org/p/jzHG-paytBG

最好的用例是关闭文件阅读器,数据库事务和在需要返回之前关闭的地方堆叠日志。

var count
defer println(count)
for { // forever
    count++
    if count == 100 {
        return
    }
}

defer pkg.DoCleanup()
something := pkg.DoSomething()
pkg.Add(something.ForCleanup)
pkg.Add(something.ForCleanup)

stream, _ := file.OpenRead("text.txt")
defer stream.Close()

// stream closed
// pkg cleaned
// 100

解决方法就像丹尼斯的答案:https://stackoverflow.com/a/40690576/9640539

答案 2 :(得分:-2)

我从here

中选择了Defer CallGoLang的以下定义

defer语句将函数调用推送到列表中。在周围函数返回后执行已保存调用的列表。延迟通常用于简化执行各种清理操作的功能。

C#版本:

选项1:

  • 使用Task API
  • 将您的DeferCall方法换入Task
  • 在正确的时间执行手动使用Start()方法或要继续使用的函数帖子,将其包装在另一个Task对象中并使用ContinueWith API执行,这将链接要执行的任务一个接一个

选项2:

  • 可以制作整个调用链Async-Await,其中所有帖子await关键字都执行主调用,这是标准的异步实现