To understand this, you first need to understand a little bit about scope and declaration space:
Scope defines where you can use a name
while declaration space focuses on
where that name is unique. Scope and
declaration space are closely related,
but there are a few subtle
differences.
A more formal definition
is that scope is an enclosing context
or region which defines where a name
can be used without qualification.
In
C#, both scope and declaration space
is defined by a statement block
enclosed by braces. That means
namespaces, classes, methods, and
properties all define both a scope and
a declaration space. As a result,
scopes can be nested and overlap each
other.
The language semantics for a try block (properly called a protected region) are that the protected region defines a scope. This means that any variables defined inside that scope are only visible by name within that scope (and any nested scopes).
The next thing you run into is that one of the ways the .NET Framework enforces type safety is to disallow unitialized variables. As a result, since you declare HttpWebRequest request;
as a local variable it has not been provided an initial value. Further, since the only place that does actually provide a value is inside a protected region, the compiler is "smart enough" to realize that the code inside the protected region might not run (as the result of an exception occurring) it is able to verify that the execution path can result in request
never having been assigned a value and issues the error.
The proper way to handle this would be using code like:
HttpWebRequest request = null;
try
{
request = (HttpWebRequest) WebRequest.Create(url);
}
catch (UriFormatException)
{
statusLabel.Text = "The address you entered was malformed, please correct it.";
statusLabel.ForeColor = Color.Red;
}
if (request != null)
{
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
}