C# 为什么这不在范围之外
最后一个括号(底部4行)关闭using语句。这里我肯定遗漏了一些明显的东西,但是代码进行编译,传递resharper,而var消息在using语句之外使用。事实上,如果我把它放在using语句中,它就无法构建 其实从这个 “using语句确保即使在调用对象上的方法时发生异常,也会调用Dispose。通过将对象放在try块中,然后在finally块中调用Dispose,可以获得相同的结果;事实上,编译器就是这样翻译using语句的。前面的代码示例在编译时扩展为以下代码(请注意,额外的大括号用于创建对象的有限范围): 消息应该已经超出范围,并且可能已被释放C# 为什么这不在范围之外,c#,using-declaration,C#,Using Declaration,最后一个括号(底部4行)关闭using语句。这里我肯定遗漏了一些明显的东西,但是代码进行编译,传递resharper,而var消息在using语句之外使用。事实上,如果我把它放在using语句中,它就无法构建 其实从这个 “using语句确保即使在调用对象上的方法时发生异常,也会调用Dispose。通过将对象放在try块中,然后在finally块中调用Dispose,可以获得相同的结果;事实上,编译器就是这样翻译using语句的。前面的代码示例在编译时扩展为以下代码(请注意,额外的大括号用于创建
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);
}
^^这是一个构造函数调用,然后是一个对象初始值设定项。下一组大括号是using
语句的主体。请看实际using关键字的括号-它们包装了整个初始化过程。它与:
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
最后一个括号(底部4行)关闭using语句
否,它将关闭资源获取。使用语句的形式如下:
var message = new MailMessage(fromAddress, toAddress);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = true;
embedded_语句
也可以是块:
using ( resource_acquisition ) embedded_statement
embedded_语句
可以访问在resource_采集中创建的变量
要将其转换为代码,请执行以下操作:
using ( resource_acquisition )
{
embedded_statement
}
使用
语句的一个基本示例如下:
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.
}
var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
};
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 whatever = new IDisposable(parameters) {PropertyName = propertyValue})
{
whatever.DoStuff();
}
因此,虽然代码分散在几行中,但仍然有效:
try
{
var whatever = new IDisposable(parameters) {PropertyName = propertyValue};
whatever.DoStuff();
}
finally
{
whatever.Dispose();
}
您误解了您的
using
语句的结尾
考虑这个简单的例子:
using (
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
}
)
{
smtp.Send(message);
}
我假设你看到这个简单的例子是有效的
可以在对象初始化期间使用(=调用构造函数) 但是,当对象初始值设定项设置多个属性时,大多数开发人员更喜欢将它们拆分为新行:
var myObject = new MyObjectClass() { Name = "Donald Trump" };
对象初始值设定项也可以使用语句在中使用:
using(/*declare and instantiate the instance of IDisposable here*/)
{
// use it here.
}
var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
};
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 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(/*declare and instantiate the instance of IDisposable here*/)
{
// use it here.
}
var myObject = new MyObjectClass() {
Name = "Donald Trump"
Age = 71,
Nickname = "Donnie"
};
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
“最后一个括号(底部4行)关闭using语句。”不,它没有。它关闭声明,然后实际语句块开始(包含单个语句smtp.Send
)。smtp.Send(message)
位于using
块内。{
在此之前,只需初始化MailMessage
。我已经重新格式化了您的代码,以明确上面的注释:)using声明中声明的变量仍然在范围内,事实上,您使用它的方式实际上是推荐的方法,从-来看,实例化obje通常更好ct在using语句中,并将其范围限制为using块。
。