2011-01-06 2 views
6

Можно создать дубликат:
What is the C# Using block and why should I use it?Использует ли лучше?

Мой вопрос: Является ли использование using(a){do something with a} лучше, чем объявление 'а' и использовать его таким образом. т.е.: более безопасный, быстрый, ...

см. примеры для пояснения.

Пример 1: (без использования)

StreamWriter sw; 
string line; 
sw = new StreamWriter("D:\\NewCon.xml"); 
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); 
sw.WriteLine("<config>"); 
for (int i = 0; i >=36; i++) 
{ 
    line = ""; 
    line = "<" + xmlnodes[i] + ">"; 
    line += vals[i]; 
    line += "</" + xmlnodes[i] + ">"; 
    sw.WriteLine(line); 
} 
sw.WriteLine("</config>"); 
sw.Close(); 
sw.Dispose();  

Пример 2: (с помощью)

string line;  
using (sw = new StreamWriter("D:\\NewCon.xml")) 
{ 
    sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); 
    sw.WriteLine("<config>"); 
    for (int i = 0; i >= 36; i++) 
    { 
     line = ""; 
     line = "<" + xmlnodes[i] + ">"; 
     line += vals[i]; 
     line += "</" + xmlnodes[i] + ">"; 
     sw.WriteLine(line); 
    } 
    sw.WriteLine("</config>"); 
} 

ответ

11

с помощью (а) {сделать что-то с}

Это означает, что когда кодовый блок выполняется с помощью a, программа вызовет a.Dispose. Вы знаете, что даже в случае исключения, у вас будет Dispose. По существу, это делается:

var a = IDisposable_Something; 
try{.....}finally{a.Dispose();} 

Это более безопасно ... на самом деле, но это не главное. Дело в том, чтобы убедиться, что ресурсы, которые необходимо очистить, выполняются, как только программа завершается с ними.

Таким образом, проблема с вашим первым примером заключается в том, что если где-то вдоль линии выбрано исключение, это не приведет к методу Dispose(). Второй будет. Вы всегда хотите, чтобы Dispose вызывается, если он есть, потому что существует вероятность того, что классы IDisposable не будут правильно написаны, и у него не будет кода, чтобы убедиться, что неуправляемые ресурсы очищены, даже если Dispose() не вызывается (это обычно делается в финализаторе). LInk to Dispose Pattern.

Единственный раз, когда я когда-либо видел, что внедрение может быть сложным, связано с прокси-сервером WCF (и вы можете обойти эту проблему). Существует ошибка, в которой, если прокси генерирует исключение время от времени, это вызовет другое исключение в методе Dispose().

http://blogs.msdn.com/b/jjameson/archive/2010/03/18/avoiding-problems-with-the-using-statement-and-wcf-service-proxies.aspx

Кроме этого, вы должны вообще попытаться поставить IDisposable объект в использовании заявлении.

+0

Огромный ответ спасибо за очищение, что для меня! –

0

Это более безопасно в том смысле, что вы склонны не забывать распоряжаться ресурсами, особенно в случае исключения (ваш код в настоящее время не улавливает).

Это более красноречиво и идиоматично, поскольку вы используете меньше строк кода, а намерение вашего кода становится намного яснее.

Так что:

StreamWriter sw; 
try 
{ 
sw = new StreamWriter("D:\\epkDATA\\NewCon.xml"); 
... 
} 
finally 
{ 
sw.Dispose(); 
} 

эквивалентно:

using(StreamWriter sw = new StreamWriter("D:\\epkDATA\\NewCon.xml")) 
{ 
... 
} 
6

Если исключение в первом примере, то ресурс не будет удален.

Использование using гарантирует, что ресурс будет удален даже при возникновении исключения.

+0

Почти то, что я имел в своем поле «Ответить», прежде чем я надену новые ответы. – Rangoric

1

Прежде всего, код в примере 1, должны быть обернуты в Try /, наконец, блок для того, чтобы быть функционально эквивалентны с кодом в примере 2.

То есть, я всегда любил «с помощью» блоки для такого кода. Я думаю, что это вообще приводит к более читаемому коду. Что касается безопасности или производительности, вы не увидите большой разницы между примером 1 и примером 2, предоставляя вам использовать блок try/finally в первом примере!

0

Использование using безопаснее, потому что вы гарантировали освобождение ресурсов, заявленных при использовании (...) скобок, даже если произошла какая-либо ошибка или неожиданный выход.

0

В дополнение к предыдущим ответам и наиболее импортируемой части, если возникает исключение, обеспечивается вызов dispose().

2

Пример 1 никогда не должен быть выполнен. Если выбрано исключение, ваш звонок Dispose() никогда не произойдет, что может быть плохо. using гарантирует выполнение Dispose(). Единственная хорошая альтернатива пример 1 (кроме using) будет:

var iDisposableObject = new YourDisposableConstructor(); 
try 
{ 
    // some code 
} 
finally 
{ 
    iDisposableObject.Dispose(); 
} 
0

если ClassA наследовать от IDisposing.A «с помощью» шаблона равно следующее:

IDisposable iDisposableObject = new YourDisposableConstructor(); 
try 
{ 
    // some code 
} 
finally 
{ 
    iDisposableObject.Dispose(); 
} 

поэтому мы бы лучше использовать образец использования

Смежные вопросы