C# `使用带有未初始化变量的`statement是不可能的,也不是最终的,那么如何正确地处理它呢?

C# `使用带有未初始化变量的`statement是不可能的,也不是最终的,那么如何正确地处理它呢?,c#,C#,假设我有一个实现IDisposable的类DisposableObject。它有可能从任何构造函数和DoStuff函数引发异常。我想这样做,以便无论发生什么情况,都能正确地处理对象: 编辑:我希望避免重复代码,因此不希望在每个if/else块中使用(代码比这里复杂得多) edit2:是的try/finally错误,将其更改为使用未分配的局部变量 using (DisposableObject worker) { if(/*condition*/) worker = new

假设我有一个实现IDisposable的类
DisposableObject
。它有可能从任何构造函数和DoStuff函数引发异常。我想这样做,以便无论发生什么情况,都能正确地处理对象:

编辑:我希望避免重复代码,因此不希望在每个if/else块中使用(代码比这里复杂得多)

edit2:是的try/finally错误,将其更改为使用未分配的局部变量

using (DisposableObject worker)
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)
    worker.DoStuff();
}
但是我不能,因为编译器说我必须在using语句中提供一个初始值设定项。 我也不能使用try/finally:

DisposableObject worker;
try
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)
    worker.DoStuff();
}
finally
{
    worker.Dispose();
}
编译器说使用未分配的局部变量“worker”

那我该怎么办?显然我不能就这样走

DisposableObject worker;
if (/*condition*/)
    worker = new DisposableObject(/*args*/)
else
    worker = new DisposableObject(/*other args*/)
worker.DoStuff();
worker.Dispose();

因为我不能确定是否曾经访问过Dispose()函数。

实际上,编译器说您正在使用一个可能未初始化的变量,所以只需初始化它:

DisposableObject worker = null;
try
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)
    worker.DoStuff();
}
finally
{
    if(worker != null)
        worker.Dispose();
}

实际上,编译器说您正在使用一个可能未初始化的变量,所以只需初始化它:

DisposableObject worker = null;
try
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)
    worker.DoStuff();
}
finally
{
    if(worker != null)
        worker.Dispose();
}

我发现将创建和使用转移到单独的方法(通常使用工厂,但为了简洁起见,这里显示了私有方法)很有用:

这意味着可以使用using块(而不必初始化为null并使用try…finally):

注意:如果工厂方法在实例化创建的实体后需要对其执行任何操作,则仍应释放该对象并重新引发异常:

public DisposableObject Create() 
{
  DisposableObject entity = new DisposableEntity();
  try 
  {
    //Some operations involving entity
  }
  catch
  {
    entity.Dispose();
    throw;
  }
}

我发现将创建和使用转移到单独的方法(通常使用工厂,但为了简洁起见,这里显示了私有方法)很有用:

这意味着可以使用using块(而不必初始化为null并使用try…finally):

注意:如果工厂方法在实例化创建的实体后需要对其执行任何操作,则仍应释放该对象并重新引发异常:

public DisposableObject Create() 
{
  DisposableObject entity = new DisposableEntity();
  try 
  {
    //Some operations involving entity
  }
  catch
  {
    entity.Dispose();
    throw;
  }
}
那么:

DisposableObject worker = null;
try
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)

    worker.DoStuff();
}
finally
{
    if (worker != null)
    {
        worker.Dispose();
    }
}
那么:

DisposableObject worker = null;
try
{
    if(/*condition*/)
        worker = new DisposableObject(/*args*/)
    else
        worker = new DisposableObject(/*other args*/)

    worker.DoStuff();
}
finally
{
    if (worker != null)
    {
        worker.Dispose();
    }
}

如果参数太复杂,可以创建包含参数的包装器类。然后在另一个包含复杂If/else的方法中创建参数。从这里,您可以正确使用第一个示例中的using块&您将确保调用Dispose()。

如果参数太复杂,您可以创建一个包含参数的包装类。然后在另一个包含复杂If/else的方法中创建参数。从这里,您可以正确地使用第一个示例中的using块&您将确保Dispose()被调用。

您可以围绕DisposableObject编写一个包装类,该类接受参数,try/catch是否以某种方式在内部执行并通知您错误?

您可以围绕DisposableObject编写一个包装类,该类接受参数,try/catch是否以某种方式在内部执行并通知您错误?

使用
有两个相当简单的选项:

{
    DisposableObject worker;
    if(/*condition*/)
        worker = new DisposableObject(/*args*/);
    else
        worker = new DisposableObject(/*other args*/);
    using (worker)
    {
        worker.DoStuff();
    }
}


其他人给出了其他同样有效的可能性,即避免使用
或重构代码,但我相信这与您已经拥有的最接近。

使用
有两个相当简单的选择:

{
    DisposableObject worker;
    if(/*condition*/)
        worker = new DisposableObject(/*args*/);
    else
        worker = new DisposableObject(/*other args*/);
    using (worker)
    {
        worker.DoStuff();
    }
}



其他人也给出了其他同样有效的可能性,即避免使用
或重构代码,但我相信这与您已有的最接近。

我不确定编译器如何在try/finally示例中抛出这样的错误,因为变量是声明的(尽管直到
try
块中才初始化)。您的实际代码是什么?正如BoltClock指出的,您的try/finally代码应该可以工作。尝试在其中添加一个
catch{}
,看看问题是否仍然存在。抛出异常的构造函数非常邪恶。有没有办法重构代码以避免这种情况发生。另外,如果一个实例被破坏得无法初始化,为什么您对它足够信任,想要尝试处理它?@AakashM您是对的,我将它改为使用未分配的局部变量。@确切的错误是“使用未分配的局部变量”,他只是缺少一个
DisposableObject worker=null在try/finally之外实例化我不确定编译器如何在try/finally示例中抛出这样的错误,因为变量是声明的(尽管直到
try
块中才初始化)。您的实际代码是什么?正如BoltClock指出的,您的try/finally代码应该可以工作。尝试在其中添加一个
catch{}
,看看问题是否仍然存在。抛出异常的构造函数非常邪恶。有没有办法重构代码以避免这种情况发生。另外,如果一个实例被破坏得无法初始化,为什么您对它足够信任,想要尝试处理它?@AakashM您是对的,我将它改为使用未分配的局部变量。@确切的错误是“使用未分配的局部变量”,他只是缺少一个
DisposableObject worker=null在try/finally之外实例化我喜欢这个概念。有时可能会更丑(甚至更干净),但还有另一种有趣的方式来解决它。我喜欢这个概念。有时可能会更难看(甚至更干净),但还有另一种有趣的方式来解决它。谢谢,我更改了消息。我不知道赋值null被认为是初始化。那怎么样……:)谢谢。谢谢,我更改了消息。我不知道赋值null被认为是初始化。那怎么样……:)谢谢。我真的很喜欢后一种选择;非常体贴。但我不确定它是否适合更复杂的问题。我真的很喜欢后一种选择;非常体贴。但不确定它是否适合更复杂的问题。