对局部变量的无用赋值¶
ID: cs/useless-assignment-to-local
Kind: problem
Security severity:
Severity: warning
Precision: very-high
Tags:
- maintainability
- external/cwe/cwe-563
Query suites:
- csharp-security-and-quality.qls
将值赋给局部变量,但该变量之后从未被读取,或者其值在被读取之前始终被覆盖。这意味着原始赋值没有任何效果,并且可能表明存在逻辑错误或代码不完整。
建议¶
确保仔细检查程序逻辑。如果确实不需要某个值,请考虑省略赋值。但请注意:如果右侧表达式具有副作用(例如执行方法调用),则保留该表达式以保持整体行为非常重要。
示例¶
以下示例显示了六种不同类型的对未读取值的局部变量的赋值
在
ParseInt
中,对int.TryParse
的调用的结果直接赋给未读取的局部变量success
。在
IsDouble
中,对int.TryParse
的调用的out
参数赋给未读取的局部变量i
。在
ParseDouble
中,在解析失败的情况下,对double.Parse
的调用引发的异常赋给未读取的局部变量e
。在
Count
中,ss
的元素赋给未读取的局部foreach
变量s
。在
IsInt
中,将o
(如果o
是整数)赋给未读取的局部类型测试变量i
。在
IsString
中,将o
(如果o
是字符串)赋给未读取的局部类型 case 变量s
。
using System;
class Bad
{
double ParseInt(string s)
{
var success = int.TryParse(s, out int i);
return i;
}
bool IsDouble(string s)
{
var success = double.TryParse(s, out double i);
return success;
}
double ParseDouble(string s)
{
try
{
return double.Parse(s);
}
catch (FormatException e)
{
return double.NaN;
}
}
int Count(string[] ss)
{
int count = 0;
foreach (var s in ss)
count++;
return count;
}
string IsInt(object o)
{
if (o is int i)
return "yes";
else
return "no";
}
string IsString(object o)
{
switch (o)
{
case string s:
return "yes";
default:
return "no";
}
}
}
修改后的示例消除了未读取的赋值。
using System;
class Good
{
double ParseInt(string s)
{
int.TryParse(s, out int i);
return i;
}
bool IsDouble(string s)
{
var success = double.TryParse(s, out _);
return success;
}
double ParseDouble(string s)
{
try
{
return double.Parse(s);
}
catch (FormatException)
{
return double.NaN;
}
}
int Count(string[] ss)
{
return ss.Length;
}
string IsInt(object o)
{
if (o is int)
return "yes";
else
return "no";
}
string IsString(object o)
{
switch (o)
{
case string _:
return "yes";
default:
return "no";
}
}
}
参考¶
维基百科:死存储。
MSDN,托管代码的代码分析,CA1804:删除未使用的局部变量。
Microsoft:C# 7 中的新增功能 - 弃元。
常见弱点枚举:CWE-563。