2014-10-09 50 views
1

我刚写的C#代码如下行,然后花了一两分钟的故障排除时按预期程序没有工作:(myStringoldValuenewValue都是字符串变量)当我忘记分配String.Replace()时,我可以让Visual Studio警告我吗?

myString.Replace(oldValue, newValue); 

显然,我的意图是导致myString变量被重新分配一个新的字符串等于原始myString值,但与oldValue子由newValue取代。

同样明显的(事后),该行代码没有工作,因为我要的Replace()回返回值已分配给myString:

myString = myString.Replace(oldValue, newValue); 

即使我清楚地知道,C#字符串不可变的,因此像Replace()这样的方法被写入来返回一个新的字符串实例,我仍然发现自己意外地写了不好的代码,就像上面的代码原始代码。

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

请注意,因为我在此处使用.Net框架方法(String.Replace),所以重写相关方法以使用out参数(如this similar question中所示)并不是真正的选项。

+2

不同意这是一个重复的。所有答案都集中在编写代码,以便代码不会出现这些问题。这是关于从系统库捕捉问题。 FxCop或者Resharper实际上可以非常优雅地标记这些。 – jessehouwing 2014-10-09 14:32:06

+0

你的耳朵之间应该有一个闹钟。清楚*改变某些东西但不用* ref *或* out *参数调用的方法。最便宜的工具,你可以找到。每个人都会记住它,你也犯这个错误一次。 – 2014-10-09 15:36:55

+1

@HansPassant - 当然,我同意,应该*!不过,出于某种原因,这对我个人而言是个盲点 - 我在第三次发生这种情况后(几个月内)才发布了这个问题。另外,反驳:某些方法(虽然在非基本类型上)会改变它们的参数而不用ref或out(并返回void),比如Array.Reverse方法。 – 2014-10-09 18:37:07

回答

3

您可以使用ReSharper,当您不将返回值赋给变量时,它会给出警告,指出您忽略了方法的返回值。

+0

感谢您的建议!正如我在问题中提到的那样,我希望有一个可用的免费解决方案。 – 2014-10-09 14:37:06

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)); 
       } 
      } 
     } 
    } 
} 
相关问题