IDE0071 may change type of objects passed to FormattableString
See original GitHub issueVersion Used: 3.8.0-4.20464.1+56f747b362e15a0763bad5ce4702a9b7c8949d7e
Steps to Reproduce:
using System;
class Program
{
static void Main(string[] args) => M($"{args.Length.ToString()}");
static void M(FormattableString fs)
{
foreach (object o in fs.GetArguments())
Console.WriteLine(o?.GetType());
}
}
Expected Behavior: IDE0071 does not fire (or a distinct diagnostic ID should be used for targeting FormattableString instead of string, or something like that)
Actual Behavior:
IDE0071 fires, and applying the fix (removing the .ToString()
) ends up changing the program’s behavior, outputting “System.Int32” instead of “System.String”. This is relevant when a FormattableString is being used by some utility that processes the objects in some way, based on type, e.g. in https://github.com/dotnet/runtime/blob/b39c698c628079b464650cda2540653533a84342/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs#L388-L392 where FormattableString is being used by logging and exerts customized formatting behavior based on argument type… in which case using ToString() in the interpolation is a way for the caller to opt-out of that policy.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:12 (12 by maintainers)
Given that
FormattableString
is an edge case usage, I would be fine with simply excluding instances of that type from analysis altogether. We could create a separate diagnostic for it, but it’s just not common enough to matter in practice.Fair, we can look into that as a particular fix for exactly this issue. However, as per above i’m wary about this as it would no mean extra user options for people to have to know about, extra UI to enable and distinguish these, etc. I’m not sure this case warrants it, but we can take to the team to decide.