为什么这不超出范围
why is this not out of scope
var smtp = new SmtpClient
{
Host =smtpHost,
Port = smtpPort,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, mailFromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
}
)
{
smtp.Send(message);
}
最后一个括号(从底部算起 4 行)结束了 using 语句。我一定在这里遗漏了一些明显的东西,但是代码编译,通过了 resharper,但是在 using 语句之外使用了 var 消息。事实上,如果我把它放在 using 语句中,它就无法构建。
其实从这个https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
"The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler. The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object): "
消息应该已经超出范围并且可能已被处置。
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
^^ 这是一次构造函数调用,然后是对象初始值设定项。 next 组大括号是 using
语句的主体。查看实际 using 关键字的括号 - 它们包装了整个初始化。等于:
var message = new MailMessage(fromAddress, toAddress);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = true;
The last parenthesis (4 lines from bottom) closes the using statement
否,关闭资源获取。使用语句具有以下形式:
using ( resource_acquisition ) embedded_statement
embedded_statement
也可以是块:
using ( resource_acquisition )
{
embedded_statement
}
embedded_statement
可以访问在 resource_acquisition
中创建的变量。
将其翻译成您的代码:
using (var message = new MailMessage(fromAddress, toAddress) //
{ //
Subject = subject, //
Body = body, // Resource acquisition
} //
) //
{ //
smtp.Send(message); // Embedded statement
} //
using
语句的一个基本示例是这样的:
using(/*declare and instantiate the instance of IDisposable here*/)
{
// use it here.
}
以下是如何使用 using
语句的简短示例:
using(var whatever = new IDisposable(parameters) {PropertyName = propertyValue})
{
whatever.DoStuff();
}
相当于:
try
{
var whatever = new IDisposable(parameters) {PropertyName = propertyValue};
whatever.DoStuff();
}
finally
{
whatever.Dispose();
}
因此,虽然分布在几行中,但您的代码仍然有效:
using (
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
)
{
smtp.Send(message);
}
你误解了你的 using
语句在哪里结束。
考虑这个简单的例子:
using(var myObject = new MyObjectClass())
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
我假设你看到这个简单的例子是有效的。
Object initializers 可以在对象初始化期间使用(=调用构造函数)。
var myObject = new MyObjectClass() { Name = "Donald Trump" };
但是当对象初始值设定项设置多个属性时,大多数开发人员更喜欢将它们拆分成新行:
var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
};
对象初始值设定项也可以用在 using
语句中:
using(var myObject = new MyObjectClass() { Name = "Donald Trump" })
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
当对象初始值设定项设置多个属性时,大多数开发人员更喜欢将它们拆分成新行
using(var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
})
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
请注意,在我的所有示例中,using
块的 body 从未更改过。
所以当我们现在看你的例子时:
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
}
)
{
smtp.Send(message); //IN SCOPE
}
smtp.Send(message); //THIS WOULD BE OUT OF SCOPE
如果我把你的对象初始化器变成单行语句,也许更容易理解:
using (var message = new MailMessage(fromAddress, toAddress) { Subject = subject, Body = body })
{
smtp.Send(message); //IN SCOPE
}
smtp.Send(message); //THIS WOULD BE OUT OF SCOPE
var smtp = new SmtpClient
{
Host =smtpHost,
Port = smtpPort,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, mailFromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
}
)
{
smtp.Send(message);
}
最后一个括号(从底部算起 4 行)结束了 using 语句。我一定在这里遗漏了一些明显的东西,但是代码编译,通过了 resharper,但是在 using 语句之外使用了 var 消息。事实上,如果我把它放在 using 语句中,它就无法构建。
其实从这个https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
"The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler. The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object): "
消息应该已经超出范围并且可能已被处置。
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
^^ 这是一次构造函数调用,然后是对象初始值设定项。 next 组大括号是 using
语句的主体。查看实际 using 关键字的括号 - 它们包装了整个初始化。等于:
var message = new MailMessage(fromAddress, toAddress);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = true;
The last parenthesis (4 lines from bottom) closes the using statement
否,关闭资源获取。使用语句具有以下形式:
using ( resource_acquisition ) embedded_statement
embedded_statement
也可以是块:
using ( resource_acquisition )
{
embedded_statement
}
embedded_statement
可以访问在 resource_acquisition
中创建的变量。
将其翻译成您的代码:
using (var message = new MailMessage(fromAddress, toAddress) //
{ //
Subject = subject, //
Body = body, // Resource acquisition
} //
) //
{ //
smtp.Send(message); // Embedded statement
} //
using
语句的一个基本示例是这样的:
using(/*declare and instantiate the instance of IDisposable here*/)
{
// use it here.
}
以下是如何使用 using
语句的简短示例:
using(var whatever = new IDisposable(parameters) {PropertyName = propertyValue})
{
whatever.DoStuff();
}
相当于:
try
{
var whatever = new IDisposable(parameters) {PropertyName = propertyValue};
whatever.DoStuff();
}
finally
{
whatever.Dispose();
}
因此,虽然分布在几行中,但您的代码仍然有效:
using (
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
)
{
smtp.Send(message);
}
你误解了你的 using
语句在哪里结束。
考虑这个简单的例子:
using(var myObject = new MyObjectClass())
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
我假设你看到这个简单的例子是有效的。
Object initializers 可以在对象初始化期间使用(=调用构造函数)。
var myObject = new MyObjectClass() { Name = "Donald Trump" };
但是当对象初始值设定项设置多个属性时,大多数开发人员更喜欢将它们拆分成新行:
var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
};
对象初始值设定项也可以用在 using
语句中:
using(var myObject = new MyObjectClass() { Name = "Donald Trump" })
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
当对象初始值设定项设置多个属性时,大多数开发人员更喜欢将它们拆分成新行
using(var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
})
{
string test = myObject.Name; //IN SCOPE
}
string test2 = myObject.Name; //OUT OF SCOPE
请注意,在我的所有示例中,using
块的 body 从未更改过。
所以当我们现在看你的例子时:
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
}
)
{
smtp.Send(message); //IN SCOPE
}
smtp.Send(message); //THIS WOULD BE OUT OF SCOPE
如果我把你的对象初始化器变成单行语句,也许更容易理解:
using (var message = new MailMessage(fromAddress, toAddress) { Subject = subject, Body = body })
{
smtp.Send(message); //IN SCOPE
}
smtp.Send(message); //THIS WOULD BE OUT OF SCOPE