我应该如何安全地初始化然后在不同的try块中使用一个变量
本文关键字:try 变量 一个 安全 何安全 初始化 我应该 然后 | 更新日期: 2023-09-27 18:02:58
所以,我需要使用StreamWriter类创建一个文件,写入它,然后关闭它,我想把所有潜在的不可执行的操作在try块;由于文件创建和写入操作将在不同的尝试块中,我不能在一个尝试块中初始化StreamWriter变量(创建文件),然后在另一个尝试块中使用它。我想我可以在try块外声明StreamWriter变量并将其设置为null,然后在try块中初始化它,但MSDN说"当在try块内,只初始化在其中声明的变量;否则,在块执行完成之前可能会发生异常。安全声明、初始化、使用文件流变量(或任何变量)然后销毁它的最佳实践是什么?也许我应该使用一些东西而不是StreamWriter?另外,如果没有在try块中声明变量,为什么不应该在try块中初始化它呢?谢谢。
您可以在try块之外声明它,只是要确保处理正确的处理。
StreamWriter sw = null;
try
{
sw = new StreamWriter(File.Open("test.txt", FileMode.OpenOrCreate));
sw.Write("Some text.");
}
catch
{
// Whatever you want to catch
}
finally
{
if(sw != null)
sw.Dispose();
sw = null;
}
try
{
sw = new StreamWriter(File.Open("otherfile.txt", FileMode.OpenOrCreate));
}
catch
{
// Whatever you want to catch
}
finally
{
if(sw != null)
sw.Dispose();
sw = null;
}
虽然,我不建议在多个try块中使用相同的变量,但这样做会获得什么?
为什么不这样呢:
try
{
using(var sw = new StreamWriter(File.Open("text.txt", FileMode.OpenOrCreate)))
{
sw.Write("some text");
}
}
catch
{
// handle exception
}
try
{
using(var sw = new StreamWriter(File.Open("otherfile.txt", FileMode.OpenOrCreate)))
{
sw.Write("some other text");
}
}
catch
{
// handle exception
}
在类级别定义的StreamWriter
不是方法吗?如果可能的话,我建议使用单个try块。
如果您需要处理不同的异常,请按照scottm
try
使用多个catch
块。StreamWriter的生命周期应该由using块来管理。
如果你想从两个try块中访问它,那么将变量声明移到两个try块之外的本能是正确的。MSFT指南只是试图给你留下深刻的印象,在这种情况下,如果你有可能的异常发生在声明之后,但在try块之前,他们不会被捕获,但初始化一个变量为null不会抛出异常,如果你不做任何事情,你是好的。(如果你真的担心它,你可以创建一个try/catch封装变量声明和其他try块)我个人不喜欢很多try/catch,但这是另一天的布道…
如果您想在两个不同的try块中访问一个变量,则需要在两个块之外(以某种方式)声明它。这就是简单的作用域控制。
为什么不呢?我猜原因是您可能会遇到异常,而不知道变量是否已初始化。所以在T/C/F块末端的状态是不确定的。如果你能确定状态是确定的,那么它是OK的,IMO。
我认为MSDN的意思是有可能通过声明T
类型的变量来调用T
的静态构造函数,从而导致在try
块之外抛出异常。
在您的示例中,我没有看到在try
块之外声明变量的任何问题。就照scottm的建议去做吧。
在声明中将变量设置为null与初始化它相同。它只是不包含对任何真实对象的有效引用,但您可以对此进行测试。你不能测试未初始化的变量:如果你有一个可能导致使用未初始化变量的路径,你会得到编译错误。
在try…Catch块,但不要初始化它。在块内进行初始化。你提到的MSDN文章似乎暗示这不是一个好主意,但我不明白为什么。
声明不会失败,但初始化可能失败。
或者,您可以嵌套try…Catch块,所以你可以在外部块中声明/初始化它,然后进一步尝试…捕获其中的块。
我建议使用using
关键字,像这样:
try {
using(StreamWriter sw = new (...)) {
//use stream here
}
}
catch(Exception ex) {}
使用将被保证,通过设计,StreamWriter
将被关闭,并在退出该块时处理,即使发生异常,因为using
实际上在IL中注入try/finally
子句。如果不可能这样做,我会认真考虑修改调用的体系结构,如果可能的话。
IO流的一般规则:在尽可能短的时间内打开/使用/关闭
问候。