Подтвердить что ты не робот

Любая проблема с вложением "использования" в С#?

Недавно я загрузил Visual Studio 2013, и я провел анализ кода в проекте, над которым я работаю. Его бросили пару проблем, над которыми я работаю, но в частности это касается того, как я использую "использование" IDisposable-оператора.

Вот пример моего кода:

using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte()))
{
    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
    {
        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        {
            return srDecrypt.ReadToEnd();
        }
    }
}

Я понимаю, что предупреждение Analysis пытается сказать мне, что удаление нескольких объектов таким образом может вызвать проблему, связанную с объектом.

Я уверен, что удаление на одном объекте не приведет к исключению в вышеприведенном случае. Так что я должен изменить свой код или сохранить как есть?

4b9b3361

Ответ 1

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

Просматривая другие вопросы Я считаю, что проблема связана с самим инструментом анализа кода и с правилами CA2000 и CA2202. Ложные срабатывания часто возникают при использовании различных потоков и типов считывателей с использованием операторов.

Вы должны игнорировать предупреждения и продолжать, поскольку альтернативные методы (например, try/finally) приведут к созданию плохого кода, и ваш код будет действительным.

Ответ 2

Причина MSDN

Вложенные операторы использования (использование в Visual Basic) могут приводить к нарушениям предупреждения CA2202. Если ресурс IDisposable вложенного внутреннего using statement содержит ресурс внешней инструкции using, метод Dispose вложенных ресурсов освобождает содержащиеся ресурс. Когда возникает такая ситуация, метод Dispose внешнего используя оператор пытается повторно использовать свой ресурс во второй раз.

в вашем случае. хорошо использовать его так. Итак, вы должны просто подавить предупреждение.

ИЛИ

вы можете просто уйти от уродливого способа подавления предупреждения, изменив свой код, выполнив Try/finally. Хотя, вы действительно должны избегать.

Ответ 3

Я не вижу проблемы с использованием нескольких операторов using для размещения объектов. Обычно имеет вложенные операторы и ваш код действителен.

Используя объекты разных типов, вы можете вложить однострочный синтаксис, если хотите сэкономить место и улучшить читаемость:

using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte()))
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
     return srDecrypt.ReadToEnd();
}

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

Вы также можете подавить предупреждение (спасибо @Jordão), как описано в этом приятном ответе:

[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
public void MyMethodWithUsings()
{
     using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte()))
     using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
     using (StreamReader srDecrypt = new StreamReader(csDecrypt))
     {
           return srDecrypt.ReadToEnd();
     }
}

Если вы хотите удалить предупреждение, вам придется переписать свой код с помощью блока try/finally и вызвать метод Dispose() ваших объектов в блоке finally, но это будет ужасно и непросто читать код, как вы можете видеть в этом вопросе.

Ответ 4

Это повторяющаяся проблема с анализом кода и CA2000 и CA2202.

У вас есть возможность исправить эти предупреждения, не используя using, но используя try/finally/dipose. Это не рекомендуется, потому что он создает ужасный код.

Ваш код будет работать, просто подавить эти предупреждения.

Также см. fooobar.com/questions/219062/... для StreamReader/Writer и основного потока.