代码分析-不要多次处理对象
本文关键字:处理 对象 代码 | 更新日期: 2023-09-27 18:22:18
我试着在这个方法上遵循代码分析的规则:
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;
}
添加了所有的Try {} Finaly{}
块,但它仍然对我大喊大叫,说我不尊重规则2202。有人能帮我吗?
是的,我读过其他关于这个主题的帖子,并尝试过应用它,但最后我还是收到了同样的信息。
要消除cs
的CA2202警告,只需删除对其Close
方法的调用。
ms
的CA2202问题稍微复杂一些。出现警告是因为CryptoStream
厚颜无耻地处理它通过is构造函数接收的流,这意味着对ms.Close()
有一个不适当的调用,你无法避免。好消息是,这种不合时宜的处置在你的情况下没有副作用,双重处置也是如此,所以你可以放心地使用SuppressMessageAttribute
而忽略这个问题。(对于实际需要传递流以在CryptoStream
之类的不可预防的处置中幸存下来的情况,通常的技术是使用流子类,其处置可以通过其实例化代码来阻止。)
去掉这两行,它们就不需要了:
cs.FlushFinalBlock();
cs.Close();
遵循此主题的文档应该会得到以下代码:
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;
}
有关此分析警告的文档(http://msdn.microsoft.com/en-us/library/ms182334.aspx)给出了这个例子,与您的例子类似,它在操纵流:
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();
}
但这仍然给出了错误。以下将解决错误:
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();
}
原因很简单;如果作者总是为您处理流。只有在编写器未成功创建的情况下,才应该自己处理流。但我必须承认,我更喜欢下面的语法,如果你创建一个MemoryStream而不是FileStream,发生异常的可能性很小,我更愿意抑制CA。请注意,你可以使用语句进行堆栈,所以通常不需要额外的"嵌套级别"。
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}