-2
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 并且 var 消息在 using 语句之外使用。事实上,如果我把它放在 using 语句中,它就无法构建。

事实上从这个https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

“using 语句确保即使在调用对象上的方法时发生异常也会调用 Dispose。您可以通过将对象放在 try 块中,然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,这是编译器如何翻译 using 语句。前面的代码示例在编译时扩展为以下代码(注意额外的花括号以创建对象的有限范围):“

消息应该已经超出范围并且可能已处置。

4

4 回答 4

4

最后一个括号(从底部开始 4 行)关闭 using 语句

不,它关闭了资源获取。使用语句具有以下形式:

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
}                                                            //
于 2017-09-25T11:02:57.513 回答
2

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);
}
于 2017-09-25T11:05:10.410 回答
0
var message = new MailMessage(fromAddress, toAddress)
                {
                    Subject = subject,
                    Body = body,
                    IsBodyHtml = true
                }

^^ 这是一个构造函数调用,然后是一个对象初始化器。下一组大括号是using语句的主体。查看实际 using 关键字的括号 - 它们包含了整个初始化。它与以下内容相同:

var message = new MailMessage(fromAddress, toAddress);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = true;
于 2017-09-25T11:02:02.463 回答
0

你误解了你的using陈述在哪里结束。

考虑这个简单的例子:

using(var myObject = new MyObjectClass())
{
    string test = myObject.Name; //IN SCOPE
}

string test2 = myObject.Name; //OUT OF SCOPE

我假设你看到这个简单的例子是有效的。


对象初始化器可以在对象初始化期间使用(= 调用构造函数)。

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

因此,当我们现在查看您的示例时:

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
于 2017-09-25T11:11:58.133 回答