为什么try块中的代码与方法的其余部分分开?

Ros*_*oss 3 c# exception-handling

我的问题是这样的:

HttpWebRequest request;

try {
    request = (HttpWebRequest) WebRequest.Create(url);
} catch (UriFormatException) {
    statusLabel.Text = "The address you entered was malformed, please correct it.";
    statusLabel.ForeColor = Color.Red;
}

HttpWebResponse response  = (HttpWebResponse) request.GetResponse();
Run Code Online (Sandbox Code Playgroud)

我从中得到的错误是request没有给出值.显然这是因为请求的值在try块中给出.

这让我感到困惑的原因是因为在我使用的其他语言中,try块中的代码与其他代码没有分开(我忘记了这个词,可能是封装?) - 类似于方法.

我是以错误的方式来做这件事的吗?我应该在异常假设WebRequest没有抛出一个之后复制try块中的代码吗?

SLa*_*aks 12

你误解了这个错误.

request变量适用于所有代码.但是,在try块之外,不保证具有值,并且C#编译器将不允许您使用变量,除非它可以确定已经分配了变量.

具体来说,如果WebRequest.Create抛出异常,request则不会被分配给.

您可以通过在catch块外部分配值来修复它,如下所示:

HttpWebRequest request = null;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你不应该catch在这里使用一个块.
相反,你应该打电话Uri.TryCreate.

  • 实际上并不是'request`变量不能保证在`catch`块中有一个值,而是保证在整个受保护区域(try/catch对)执行后它没有值. (2认同)

Jan*_*oom 6

要解决此问题,您需要提供一个默认值HttpWebRequest request = null;.

C#和大多数C风格的语言(但不是JavaScript!)都有块范围,这就是你要找的术语.

因此,通过当前作用域的每个执行路径都应该设置request参数.所以

//create new scope (every '{ }' block has it's own scope, so you can also create
// a new one, by just wrapping some code inside accolades.
{
    if(a) request = something;
    else if(b) // do nothing
}

request.DoSomething();
Run Code Online (Sandbox Code Playgroud)

像在新范围中一样,只会失败通过a集合的执行路径request.同样的事情try-catch.既trycatch应该设置请求变量.


块范围也非常有用,就像这样有效:

// first-part-of-my-app
{
    int myVariable = 10;
}

// second-part
{
    string myVariable = "hi"; // is valid
}
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的.这里的问题是明确的分配,而不是范围. (2认同)
  • 我不得不同意SLaks; 问题中给出的代码示例不同意这个答案. (2认同)