2017-09-25 120 views
-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語句確保處置是即使當你調用對象的方法發生異常調用。您可以通過將對象try塊內達到同樣的效果然後在finally塊中調用Dispose;實際上,這就是編譯器翻譯using語句的方式。前面的代碼示例在編譯時展開爲以下代碼(請注意額外的大括號來爲對象創建有限的作用域):「

消息應該已經超出範圍並可能處置。

+7

「最後的括號(4線從底部)關閉使用聲明。「不,它沒有。它關閉聲明,然後開始實際的語句塊(包含單個語句「smtp.Send」)。 –

+4

'smtp.Send(message)'位於'using'塊中。之前的'{}'只是MailMessage的初始化。 –

+0

我已將代碼重新格式化,以使上述評論清楚:) –

回答

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 
}               // 
0
var message = new MailMessage(fromAddress, toAddress) 
       { 
        Subject = subject, 
        Body = body, 
        IsBodyHtml = true 
       } 

^^這是一個構造函數調用,然後是一個對象初始化器。 下一步一套大括號是using聲明的正文。查看實際使用關鍵字的括號 - 它們包含了整個初始化過程。這是一樣的:

var message = new MailMessage(fromAddress, toAddress); 
message.Subject = subject; 
message.Body = body; 
message.IsBodyHtml = true; 
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); 
} 
0

你誤會您的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塊的已經從未改變

所以,當我們現在就來看看你的例子:

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 
相關問題