我刚刚编写了以下C#代码行,然后在程序没有按预期工作时花了几分钟进行故障排除:
myString.Replace(oldValue, newValue);
(myString
,oldValue
和newValue
都是字符串变量。)
显然,我的意图会导致myString
变量重新分配一个等于原始myString
值的新字符串,但oldValue
子字符串被替换为newValue
。
同样明显(事后看来),这行代码没有用,因为我应该将Replace()
的返回值分配回myString:
myString = myString.Replace(oldValue, newValue);
尽管我很清楚C#字符串是不可变的,因此编写像Replace()
这样的方法来返回一个新的字符串实例,我仍然发现自己不小心编写了错误的代码,就像上面的原始代码行一样有时候。
我的问题是:在这种情况下,我可以让Visual Studio给我一个编译时警告,以免我需要在运行时手动查找和诊断问题吗?
请注意,由于我在这里使用.Net框架方法(String.Replace),所以重写相关方法以使用out
参数(如this similar question中所示)isn&#39真的是一个选择。
答案 0 :(得分:3)
您可以使用ReSharper,当您没有将返回值分配给变量时,它会向您发出警告,指示您忽略方法的返回值。
答案 1 :(得分:1)
I have created a custom FxCop rule that handles this case for ignoring调用不可变类型方法的结果。
基本要点是:
/// <summary>
/// We need to find all Pop nodes, these are a member of the ExpressionStatement class.
/// After we find a Pop statement (which ignores the current value on the stack), we will see if the value added
/// to the stack is an instance MethodCall on an ImmutableType.
/// </summary>
/// <param name="statement"></param>
public override void VisitExpressionStatement(ExpressionStatement statement)
{
if (statement == null) { throw new ArgumentNullException("statement"); }
if (statement.Expression.NodeType == NodeType.Pop)
{
VisitUnaryExpression(statement.Expression as UnaryExpression);
}
base.VisitExpressionStatement(statement);
}
/// <summary>
/// When we've found the UnaryExpression we check it for a MethodCall on an ImmutableType
/// </summary>
/// <param name="unaryExpression"></param>
public override void VisitUnaryExpression(UnaryExpression unaryExpression)
{
if (unaryExpression == null) { throw new ArgumentNullException("unaryExpression"); }
if (unaryExpression.NodeType == NodeType.Pop)
{
MethodCall call = unaryExpression.Operand as MethodCall;
if (call != null)
{
MemberBinding binding = call.Callee as MemberBinding;
if (binding.BoundMember.DeclaringType != null
&& immutableTypes.Contains(binding.BoundMember.DeclaringType.FullName))
{
Method method = binding.BoundMember as Method;
// If the method also returns an immutable Type we flag it as a problem.
if (immutableTypes.Contains(method.ReturnType.FullName))
{
this.Problems.Add(new Problem(GetResolution(), call));
}
}
}
}
}