2012-02-02 15 views
8

Próbowałem następujących zasad analizy kodu na tej metodzie:analiza Code - Nie wyrzucaj obiektów wielokrotnie

public static string Encrypt(string password) 
{ 
    string myPassword = string.Empty; 
    if (!string.IsNullOrEmpty(password)) 
    { 
     myPassword = password; 
     byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword); 
     SymmetricAlgorithm mCSP = new RijndaelManaged(); 
     mCSP.Key = _key; 
     mCSP.IV = _initVector; 
     using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV)) 
     { 
      using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 
      { 
       using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write)) 
       { 
        cs.Write(Value, 0, Value.Length); 
        cs.FlushFinalBlock(); 
        cs.Close(); 
        myPassword = Convert.ToBase64String(ms.ToArray()); 
       } 
      } 
     } 
    } 
    return myPassword; 
} 

dodaniu wszystkich Try {} Finaly{} bloki, ale to wciąż wrzeszczał na mnie, że ja nie regułę szacunek 2202. ktoś może mi w tym pomóc?

tak, czytałem inne posty na ten temat i próbowałem go zastosować, , ale na końcu nadal otrzymuję tę samą wiadomość.

Odpowiedz

13

aby pozbyć się ostrzeżenie CA2202 dla cs, po prostu usuń wywołanie do jego metody Close.

Problem CA2202 dla ms jest nieco bardziej skomplikowany. Ostrzeganie pojawia się, ponieważ CryptoStream ma zniechęcenie do pozbycia się strumienia, który otrzymał przez konstruktor, co oznacza, że ​​istnieje jedno niewłaściwe połączenie z ms.Close(), którego nie można uniknąć. Dobrą wiadomością jest to, że ta niewczesna skłonność nie ma żadnych skutków ubocznych w twoim przypadku, a to samo dotyczy podwójnego usposobienia, więc możesz bezpiecznie uderzyć w SuppressMessageAttribute i zignorować problem. (W przypadkach, w których faktycznie trzeba przejść strumień, aby przetrwać jego nieusuwalne unieszkodliwienie przez coś podobnego do CryptoStream, zwykle stosuje się podklasę strumienia, której uspójnienie można zapobiec poprzez jej kod instancji).

+2

Nie lubię tłumić żadnych "błędów", może powinienem poprawić mój kod? – Dementic

2

pozbyć się tych dwóch linii, nie są one potrzebne:

cs.FlushFinalBlock(); 
cs.Close(); 
+2

I przenieść 'mojehasło = Convert.ToBase64String (ms.ToArray());' zakresu nadrzędnego, aby upewnić się, że jest 'cs' ** ** zostały opróżnione! –

+0

Nadal otrzymuję regułę 2202 na 'ms'. – Dementic

2

Po documentation on this topic powinny prowadzić do tego kodu:

public static string Encrypt(string password) 
{ 
    string myPassword = string.Empty; 
    if (!string.IsNullOrEmpty(password)) 
    { 
     myPassword = password; 
     byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword); 
     SymmetricAlgorithm mCSP = new RijndaelManaged(); 
     mCSP.Key = _key; 
     mCSP.IV = _initVector; 
     using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV)) 
     { 
      System.IO.MemoryStream ms = null; 
      try 
      { 
       ms = new System.IO.MemoryStream() 
       var tmp = ms; 
       using (CryptoStream cs = new CryptoStream(ms, ct, 
                 CryptoStreamMode.Write)) 
       { 
        ms = null; 

        cs.Write(Value, 0, Value.Length); 
        cs.FlushFinalBlock(); 
        cs.Close(); 
        myPassword = Convert.ToBase64String(tmp.ToArray()); 
       } 
      } 
      finally 
      { 
       if(ms != null) 
        ms.Dispose(); 
      } 
     } 
    } 
    return myPassword; 
} 
+0

Nadal otrzymuję regułę 2202 na 'cs' i' ms' – Dementic

+0

@Dementic Co by było, gdybyś to zrobił, ale pozbyłeś się 'cs.Close()'? tj. kombinacja naszych odpowiedzi – Ray

+0

nawet kombinacja kodów nie będzie działać, nadal otrzymuję 2202 na 'ms' – Dementic

2

Dokumentacja ostrzeżenia o analizie (http://msdn.microsoft.com/en-us/library/ms182334.aspx) daje ten przykład, podobny do Ciebie w tym, że manipuluje strumienie:

Stream stream = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.OpenOrCreate); 
    using (StreamWriter writer = new StreamWriter(stream)) 
    { 
     stream = null; 
     // Use the writer object... 
    } 
} 
finally 
{ 
    if(stream != null) 
     stream.Dispose(); 
} 

ale nadal daje błąd. Poniższa rozwiąże błąd:

Stream stream = null; 
StreamWriter writer = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.OpenOrCreate); 
    writer = new StreamWriter(stream)) 

    // Do some stuff on the stream writer.. 
} 
finally 
{ 
    if(writer != null) 
     writer.Dispose(); 
    else if(stream != null) 
     stream.Dispose(); 
} 

Powód jest prosty; jeśli autor zawsze wyśle ​​strumień dla ciebie. Tylko w scenariuszu pisarz nie zostanie pomyślnie utworzony, jeśli sam ześlesz strumień. Ale muszę przyznać, że podoba mi się dalsza składnia, a jeśli utworzysz obiekt MemoryStream zamiast FileStream, szansa na wystąpienie wyjątku jest niewielka i wolałabym tłumić CA. Zauważ, że możesz układać stosy za pomocą instrukcji, więc dodatkowy "poziom zagnieżdżenia" często nie jest wymagany.

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate)) 
using (StreamWriter writer = new StreamWriter(stream)) 
{ 
    // Use the writer object... 
} 
+0

lubisz kopać groby?;) jeśli strumień nie zostanie pomyślnie utworzony, to nie ma potrzeby go usuwać .. tłumienie, jak to skomentowałem w powyższej odpowiedzi, nie jest czymś, co lubię robić. udało mi się naprawić kod poprzez ponowne uwzględnienie mojego kodu. – Dementic