2012-02-02 35 views
8

tôi đã thử làm theo các quy tắc của phân tích mã trên phương pháp này:phân tích Mã - Đừng vứt bỏ đối tượng nhiều lần

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; 
} 

thêm tất cả các Try {} Finaly{} khối, nhưng nó vẫn còn la hét với tôi rằng tôi không quy tắc tôn trọng 2202. ai cũng có thể cho tôi một bàn tay với điều này?

có, tôi đã đọc các bài đăng khác về chủ đề này và đã thử áp dụng nó, nhưng cuối cùng tôi vẫn nhận được cùng một thông báo.

Trả lời

13

Để thoát khỏi cảnh báo CA2202 cho cs, chỉ cần xóa cuộc gọi đến phương thức Close của nó.

Sự cố CA2202 đối với ms phức tạp hơn một chút. Cảnh báo đang cắt xén bởi vì CryptoStream có ảnh hưởng đến việc xử lý luồng mà nó nhận được qua là hàm tạo, điều đó có nghĩa là có một cuộc gọi không thích hợp tới ms.Close() mà bạn không thể tránh. Tin tốt là bố trí không kịp thời này không có tác dụng phụ trong trường hợp của bạn, và điều tương tự cũng xảy ra đối với bố cục kép, vì vậy bạn có thể tát một cách an toàn trên SuppressMessageAttribute và bỏ qua vấn đề. (Đối với những trường hợp bạn thực sự cần truyền luồng để tồn tại cách bố trí không thể khắc phục của nó bằng một cái gì đó như CryptoStream, kỹ thuật thông thường là sử dụng phân lớp dòng có bố cục có thể được ngăn chặn bằng mã instantiating của nó.)

+2

tôi không thực sự thích suppresing bất kỳ "lỗi", có lẽ tôi nên refactor mã của tôi? – Dementic

2

Loại bỏ hai dòng này, họ không cần thiết:

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

Và di chuyển 'myPassword = Convert.ToBase64String (ms.ToArray());' thành phạm vi gốc, để đảm bảo rằng 'cs' ** đã ** được xóa! –

+0

Vẫn nhận quy tắc 2202 trên 'ms'. – Dementic

2

Tiếp theo documentation on this topic nên dẫn đến mã này:

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

Vẫn nhận quy tắc 2202 trên 'cs' và' ms' – Dementic

+0

@Dementic Còn nếu bạn đã làm điều này, nhưng đã loại bỏ 'cs.Close()'? tức là sự kết hợp các câu trả lời của chúng tôi – Ray

+0

thậm chí kết hợp các mã sẽ không hoạt động, tôi vẫn nhận được 2202 trên 'ms' – Dementic

2

Tài liệu về cảnh báo phân tích này (http://msdn.microsoft.com/en-us/library/ms182334.aspx) cho ví dụ này, tương tự như ví dụ của bạn ở chỗ nó thao tác với các luồng:

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(); 
} 

nhưng điều này vẫn gây ra lỗi. Phần sau sẽ giải quyết lỗi:

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(); 
} 

Lý do rất đơn giản; nếu người viết sẽ luôn xử lý luồng cho bạn. Chỉ trong kịch bản, người viết không được tạo thành công nếu bạn tự mình vứt bỏ luồng. Nhưng tôi phải thừa nhận tôi thích cú pháp sau nhiều hơn nữa, và nếu bạn tạo một MemoryStream thay vì một FileStream thì cơ hội của một ngoại lệ xảy ra là nhỏ và tôi muốn loại bỏ CA. Xin lưu ý rằng bạn có thể ngăn xếp bằng cách sử dụng câu lệnh, do đó, không cần thêm 'cấp độ làm tổ' bổ sung.

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

bạn thích đào lên mộ?;) nếu luồng không được tạo thành công, thì không cần phải vứt bỏ nó .. đàn áp, như tôi đã nhận xét trong câu trả lời ở trên, không phải là điều tôi muốn làm. tôi đã quản lý để sửa mã bằng cách tính lại mã của tôi. – Dementic

Các vấn đề liên quan