Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/commons/Strings.qll
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ImplicitToStringExpr extends Expr {
m = p.getCallable()
|
m = any(SystemTextStringBuilderClass c).getAMethod() and
m.getName().regexpMatch("Append(Line)?") and
m.getName() = "Append" and
not p.getType() instanceof ArrayType
or
p instanceof StringFormatItemParameter and
Expand Down
5 changes: 3 additions & 2 deletions csharp/ql/src/Useless code/RedundantToStringCall.ql
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ import semmle.code.csharp.frameworks.System
from MethodCall mc
where
mc instanceof ImplicitToStringExpr and
mc.getTarget() instanceof ToStringMethod
select mc, "Redundant call to 'ToString' on a String object."
mc.getTarget() instanceof ToStringMethod and
not mc.getQualifier() instanceof BaseAccess
select mc, "Redundant call to 'ToString'."
7 changes: 7 additions & 0 deletions csharp/ql/src/change-notes/2026-04-17-useless-to-string.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
category: minorAnalysis
---
* The query `cs/useless-tostring-call` has been updated to avoid false
positive results in calls to `StringBuilder.AppendLine` and calls of
the form `base.ToString()`. Moreover, the alert message has been
made more precise.
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
using System;
using System.Text;

class RedundantToString
{
public void M(object o)
{
Console.WriteLine(o.ToString()); // BAD
Console.WriteLine(o.ToString()); // $ Alert
Console.WriteLine(o); // GOOD

Console.WriteLine($"Hello: {o.ToString()}"); // BAD
Console.WriteLine($"Hello: {o.ToString()}"); // $ Alert
Console.WriteLine($"Hello: {o}"); // GOOD

Console.WriteLine("Hello: " + o.ToString()); // BAD
Console.WriteLine("Hello: " + o.ToString()); // $ Alert
Console.WriteLine("Hello: " + o); // GOOD

var sb = new StringBuilder();
sb.Append(o.ToString()); // $ Alert
sb.Append(o); // GOOD
sb.AppendLine(o.ToString()); // GOOD
Comment thread
geoffw0 marked this conversation as resolved.

Console.WriteLine($"Hello: {base.ToString()}"); // GOOD
Comment thread
geoffw0 marked this conversation as resolved.
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
| RedundantToStringCall.cs:7:27:7:38 | call to method ToString | Redundant call to 'ToString' on a String object. |
| RedundantToStringCall.cs:10:37:10:48 | call to method ToString | Redundant call to 'ToString' on a String object. |
| RedundantToStringCall.cs:13:39:13:50 | call to method ToString | Redundant call to 'ToString' on a String object. |
| RedundantToStringCallBad.cs:7:45:7:56 | call to method ToString | Redundant call to 'ToString' on a String object. |
| RedundantToStringCall.cs:8:27:8:38 | call to method ToString | Redundant call to 'ToString'. |
| RedundantToStringCall.cs:11:37:11:48 | call to method ToString | Redundant call to 'ToString'. |
| RedundantToStringCall.cs:14:39:14:50 | call to method ToString | Redundant call to 'ToString'. |
| RedundantToStringCall.cs:18:19:18:30 | call to method ToString | Redundant call to 'ToString'. |
| RedundantToStringCallBad.cs:7:45:7:56 | call to method ToString | Redundant call to 'ToString'. |
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Useless code/RedundantToStringCall.ql
query: Useless code/RedundantToStringCall.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ class Bad
{
static string Hello(object o)
{
return string.Format("Hello, {0}!", o.ToString());
return string.Format("Hello, {0}!", o.ToString()); // $ Alert
}
}
Loading