Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CA1859: Use concrete types when possible for improved performance, suggesting wrong type #7574

Open
ygoe opened this issue Feb 13, 2025 · 1 comment

Comments

@ygoe
Copy link

ygoe commented Feb 13, 2025

Analyzer

Diagnostic ID: CA2013: Do not use ReferenceEquals with value types

Analyzer source

SDK: Built-in CA analyzers in .NET 5 SDK or later

Version: SDK 5.0.100

OR

NuGet Package: Microsoft.CodeAnalysis.NetAnalyzers

Version: 8.0.0

Describe the bug

I don't know if any of the above information is relevant or correct, I don't understand it so I haven't touched it. If I'm supposed to enter anything in there, please make it clear in the template.

So, the analyzer "CA1859: Use concrete types when possible for improved performance" gives me a false suggestion. If I follow it, my code breaks immediately.

Steps To Reproduce

Code:

	private static object? Multiply(object? leftValue, object? rightValue)
	{
		if (ConvertToDoubleOrString(leftValue, out double left, out string? leftStr))
		{
			if (ConvertToDoubleOrString(rightValue, out double right, out string? rightStr))
			{
				return left * right;
			}
			return Repeat(rightStr, (int)left);
		}
		else if (ConvertToDoubleOrString(rightValue, out double right, out string? _))
		{
			return Repeat(leftStr, (int)right);
		}
		throw new FormatException("The * operator does not accept two string operands.");

		static string? Repeat(string? str, int count)
		{
			if (str == null)
				return null;
			var sb = new StringBuilder(str.Length * count);
			while (count-- > 0)
			{
				sb.Append(str);
			}
			return sb.ToString();
		}
	}

	// Defined in a base class:
	protected static bool ConvertToDoubleOrString(object? value, out double doubleValue, out string? stringValue)
	{
		doubleValue = 0;
		stringValue = null;
		if (value == null)
		{
			return false;
		}
		if (value is double d)
		{
			doubleValue = d;
			return true;
		}
		stringValue = Convert.ToString(value, CultureInfo.InvariantCulture)!;
		return double.TryParse(stringValue, CultureInfo.InvariantCulture, out doubleValue);
	}

Expected behavior

No suggestion, object? is already the best return type.

Actual behavior

Analyzer suggests to change return type of Multiply to string? for better performance.

Additional context

  • .NET 9
  • Visual Studio 17.12.4
@ygoe
Copy link
Author

ygoe commented Feb 13, 2025

At the same time, the analyzer doesn't suggest anything in these methods where I'd expect it to do:

	private static object ShiftRight(object? leftValue, object? rightValue)
	{
		int left = (int)ConvertToDouble(leftValue);
		int right = (int)ConvertToDouble(rightValue);
		return (double)(left >> right);
	}

	private static object BitwiseOr(object? leftValue, object? rightValue)
	{
		int left = (int)ConvertToDouble(leftValue);
		int right = (int)ConvertToDouble(rightValue);
		return (double)(left | right);
	}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant