【问题标题】:Define a variable in a try block in C#在 C# 的 try 块中定义变量
【发布时间】:2021-10-13 13:22:56
【问题描述】:

我不想拥有超深的嵌套块,所以在变量初始化可能出错的情况下,我更愿意这样做:

try
{
    var foo = GetFoo();
}
catch (FooException)
{
   Console.Write(...);
   throw;
}

var bar = GetBar(foo);

当然它不会编译。我不允许在初始化它的 try-block 之外使用foo

在我看来,将完整的类型规范放在块的正上方也很糟糕:

FooType foo;
try
{
    foo = GetFoo();
}
catch (FooException)
{
   Console.Write(...);
   throw;
}

var bar = GetBar(foo);

即使在不太极端的情况下,例如 int foo = 0;,它已经感觉很脏,尤其是在未使用的初始值令人困惑的情况下。 catch 块无论如何都会退出程序。

我如何尝试初始化一个变量并在该范围之外使用它,以最少的重复和最少的字符输入?


为什么我认为我不喜欢提升变量声明的解决方案:

我更喜欢避免类型化的变量声明。我不喜欢重复。我不喜欢变量声明与其初始化之间的脱节。我不喜欢设置未使用的初始值。最后两点可能来自与违反不变性的潜意识关联;我倾向于在概念上喜欢尽可能多的变量 readonly 并且单独声明和初始化与该模式相矛盾。

【问题讨论】:

标签: c#


【解决方案1】:

这样做的一种方法是将初始化逻辑放入另一个方法中并用try/catch 包装它,这样你就可以:

var foo = InitializeFoo();
var bar = GetBar(foo);

private Foo InitializeFoo() 
{
     try {
         // initalize and return foo
     }
     catch {
        throw;
     }
}

您可以通过将delegate 传递给指定初始化逻辑并将其用于其他任何事情的Initialize 方法来概括这一点。

public T InitializeVariable<T>(Func<T> initializeAction)
{
     try {
         var x = initializeAction();
         return x;
     }
     catch {
        throw;
     }
}

【讨论】:

  • 初始化器也是应该决定发生错误的那个。我只是在写throw; 但当然InitializeFoo 的调用者也是想要指定错误行为的人
  • @theonlygusti 那么你的意思是必须捕获的异常类型也可以改变吗?
  • catch (...Exception) { // do some cleanup, debug logging,一切以调用者意愿为准。
  • @theonlygusti 这也可以通过使用回调委托进行错误处理来概括。
  • 为什么你觉得这种TryInitialize(initializer, onError)的方法不在语言里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 2017-11-02
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 2022-08-19
  • 2012-05-13
相关资源
最近更新 更多