当忘记分配String.Replace()时,我可以让Visual Studio警告我吗?

时间:2014-10-09 14:25:32

标签: c# visual-studio compiler-warnings

我刚刚编写了以下C#代码行,然后在程序没有按预期工作时花了几分钟进行故障排除:

myString.Replace(oldValue, newValue);

myStringoldValuenewValue都是字符串变量。)

显然,我的意图会导致myString变量重新分配一个等于原始myString值的新字符串,但oldValue子字符串被替换为newValue

同样明显(事后看来),这行代码没有用,因为我应该将Replace()的返回值分配回myString:

myString = myString.Replace(oldValue, newValue);

尽管我很清楚C#字符串是不可变的,因此编写像Replace()这样的方法来返回一个新的字符串实例,我仍然发现自己不小心编写了错误的代码,就像上面的原始代码行一样有时候。

我的问题是:在这种情况下,我可以让Visual Studio给我一个编译时警告,以免我需要在运行时手动查找和诊断问题吗?

请注意,由于我在这里使用.Net框架方法(String.Replace),所以重写相关方法以使用out参数(如this similar question中所示)isn&#39真的是一个选择。

2 个答案:

答案 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));
                }
            }
        }
    }
}