C#,有没有像golang一样的'Defer Call'?

C#, is there 'Defer Call' like golang?

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

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

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

如何在 C# 中执行此操作?

我需要这样的golang defer tutorial

我从 here

中获取了 GoLangDefer Call 的以下定义

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

C#版本:

选项 1:

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

选项 2:

  • 可以使整个调用链Async-Await,其中所有post await关键字都在主调用完成时执行,这是标准的异步实现

最接近的等效语言是 try-finally:

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

最接近的等效框架是 IDisposable + using:

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

就我个人而言,defer 术语让我感到困惑,因为 这不是 "deferred execution"(现在安排 - 稍后执行,可以通过任务实现), 但是某种 RAII 实现。

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

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

由于 defer 在 go 中像堆栈一样工作,因此按顺序调用延迟函数会导致相反的顺序。

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

最好的用例是关闭文件读取器、数据库事务和堆叠日志,其中需要在 returning 之前关闭。

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

解决方法就像丹尼斯的回答:

您可以使用 System.Reactive.Disposables.Disposable

来实现
void Function()
{
    string fileName = "InputFile.txt";
    using var defer = Disposable.Create(() => { File.Delete(fileName); });

    WriteFile(fileName);
    ConvertFile(fileName, "OutputFile.txt");
}