Какова связь между ключевым словом using и интерфейсом IDisposable?
Если я использую using
Ключевое слово, я все еще должен реализовать IDisposable
?
7 ответов
Если вы используете using
оператор вложенный тип должен уже реализовать IDisposable
в противном случае компилятор выдаст ошибку. Так что считайте IDisposable реализацию обязательным условием использования.
Если вы хотите использовать using
заявление о вашем пользовательском классе, то вы должны реализовать IDisposable
для этого. Однако это отчасти отстает, потому что нет смысла делать это ради этого. Только если у вас есть что-то, что можно утилизировать как неуправляемый ресурс, вы должны его реализовать.
// To implement it in C#:
class MyClass : IDisposable {
// other members in you class
public void Dispose() {
// in its simplest form, but see MSDN documentation linked above
}
}
Это позволяет вам:
using (MyClass mc = new MyClass()) {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
} // Here the .Dispose method will be automatically called.
По сути, это то же самое, что писать:
MyClass mc = new MyClass();
try {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
}
finally { // always runs
mc.Dispose(); // Manual call.
}
Вы не можете иметь одно без другого.
Когда вы пишете:
using(MyClass myObj = new MyClass())
{
myObj.SomeMthod(...);
}
Компилятор сгенерирует что-то вроде этого:
MyClass myObj = null;
try
{
myObj = new MyClass();
myObj.SomeMthod(...);
}
finally
{
if(myObj != null)
{
((IDisposable)myObj).Dispose();
}
}
Так что, как вы можете видеть, имея using
В качестве ключевого слова предполагается / требуется, чтобы IDisposable был реализован.
Вы путаете вещи. Вы можете использовать ключевое слово "using" только для того, что реализует IDisposable.
Редактировать: если вы используете ключевое слово using, вам не нужно подробно вызывать Dispose, он будет вызван автоматически в конце блока using. Другие уже опубликовали примеры того, как оператор using преобразуется в оператор try - finally с вызовом Dispose в блоке finally.
Да, ключевое слово using является синтаксическим сахаром для этого типа шаблона...(из msdn)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
Редактировать: полезный пример.
Когда вы обнаружите, что вы делаете что-то последовательно в разделе finally, например, возвращаете курсор по умолчанию после установки его в качестве курсора ожидания, это кандидат на этот шаблон...
public class Busy : IDisposable
{
private Cursor _oldCursor;
private Busy()
{
_oldCursor = Cursor.Current;
}
public static Busy WaitCursor
{
get
{
Cursor.Current = Cursors.WaitCursor;
return new Busy();
}
}
#region IDisposable Members
public void Dispose()
{
Cursor.Current = _oldCursor;
}
#endregion
}
Называется как...
using(Busy.WaitCursor)
{
// some operation that needs a wait cursor.
}
Использование будет утилизировать только одноразовые предметы. Поэтому обертывание блока using вокруг объекта, который не реализует IDisposable , довольно бесполезно, фактически приведет к ошибке компилятора.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Как правило, когда вы используете объект IDisposable, вы должны объявить и создать его экземпляр в операторе using. Оператор using вызывает метод Dispose для объекта правильным образом, а также вынуждает сам объект выходить из области видимости, как только вызывается Dispose. Внутри блока using объект доступен только для чтения и не может быть изменен или переназначен.
Оператор using гарантирует, что Dispose вызывается, даже если возникает исключение, когда вы вызываете методы объекта. Вы можете достичь того же результата, поместив объект в блок try, а затем вызвав Dispose в блоке finally; на самом деле, именно так оператор using переводится компилятором.
Вы должны реализовать IDisposable для использования с помощью. Если вы попытаетесь использовать using() для типа, который не реализует IDisposable, вы получите следующую ошибку времени компиляции:
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'
Ключевое слово using уже реализовано, поэтому, если вы используете ключевое слово using, вам не нужно вызывать IDisposable.