CA2202: объект можно утилизировать более одного раза - PullRequest
0 голосов
/ 27 ноября 2018

В следующем фрагменте кода я получаю следующее предупреждение, но не могу понять, почему предупреждение

CA2202: Microsoft.Usage: объект 'memStream' может быть удален несколько раз в методе 'Encrypt(строка).Во избежание генерации исключения System.ObjectDisposedException не следует вызывать метод Dispose для объекта более одного раза.

Код:

string Encrypt(string toEncrypt)
{
    byte[] key = ...
    byte[] iv = ...

    using (AesCng aes = new AesCng())
    using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
    using (MemoryStream memStream = new MemoryStream())
    using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
    {
        UTF7Encoding encoder = new UTF7Encoding();
        byte[] bytes = encoder.GetBytes(toEncrypt);

        cryptoStream.Write(bytes, 0, bytes.Length);
        cryptoStream.FlushFinalBlock();

        return Convert.ToBase64String(memStream.ToArray());
    }
}

Объект CryptoStream, в лучшем случаенасколько я знаю, не распоряжаться переданным в Stream, когда оно само уничтожается.Так как же возможно, что переменная memStream может быть удалена более одного раза?

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Вы можете использовать перегруженный конструктор CryptoStream с параметром leftOpen.

И в этом нет необходимости, поскольку объект CryptoStream использует блок

cryptoStream.FlushFinalBlock();

Код:

string Encrypt(string toEncrypt)
{
    byte[] key = ...
    byte[] iv = ...

    using (AesCng aes = new AesCng())
    using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
    using (MemoryStream memStream = new MemoryStream())
    using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write,true))
    {
        UTF7Encoding encoder = new UTF7Encoding();
        byte[] bytes = encoder.GetBytes(toEncrypt);

        cryptoStream.Write(bytes, 0, bytes.Length);

        return Convert.ToBase64String(memStream.ToArray());
    }
}

leftOpen: значение true, чтобы не закрывать нижележащий поток при удалении объекта CryptoStream

CryptoStream ctor

0 голосов
/ 27 ноября 2018

CryptoStream.Dispose() по умолчанию удалит базовый поток.Если вам не нужно такое поведение, вам нужно использовать конструктор overload , который явно делает основной поток открытым, когда уничтожается CryptoStream.

Вы можете увидеть, как это реализовано здесь .

...