Don't report CA1704 for numeric type parameter names (T1, T2, …)
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 1.3k
- PR merge metrics
- PR metrics pending
Description
### Describe the bug
CA1704 (IdentifiersShouldBeSpelledCorrectly) reports numeric type parameter names such as
`T1` and `T2` as unmeaningful. That is the multi-arity convention used by `Func`,
`Action`, `Tuple` and `HashCode.Combine`, so code mirroring those
signatures gets one diagnostic per type parameter per overload.
The rule is inconsistent with itself: `T` is not reported and `T10` is not reported, but `T1` is.
### Steps to reproduce
1. Add a PackageReference to Text.Analyzers.
2. Enable the rule: dotnet_diagnostic.CA1704.severity = warning
3. Build this file:
```csharp
public static class C
{
public static int Combine(T1 value1, T2 value2) => 0;
public static int Combine(T10 value) => 0;
}
```
### Expected behavior
No CA1704 diagnostics. `T1` and `T2` are the framework's own type parameter naming convention,
and the same analyzer already ignores `T` and `T10`.
### Actual behavior
CA1704: On method 'C.Combine(T1, T2)', consider providing a more meaningful name than
generic type parameter name 'T1' (and the same for 'T2')
`Combine` produces nothing.
Cause: the unmeaningful check tests `symbolName.Length == 1` against a name that
`RemovePrefixIfPresent('T', …)` has already stripped, so `"T1"` arrives as `"1"` (length 1,
reported), `"T10"` as `"10"` (length 2, not reported) and `"T"` as `""` (length 0, not reported).
The spelling half of the same method already exempts numeric words via `IsWordNumeric`.
### Is this a regression?
No. Present since the rule was implemented; the parameter and the length check have not
changed since that commit.
Was correct as earlier FxCop rule.
### Are there any workarounds?
Only blunt ones: suppress CA1704 for the affected files, or disable the rule - which also
disables its dictionary-driven spell checking, since all 18 CA1704 descriptors share the id.
### dotnet --info output
```console
.NET SDK:
Version: 10.0.301
Commit: 96856fd726
Workload version: 10.0.300-manifests.8c7d7c03
MSBuild version: 18.6.4+96856fd72
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26200
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\10.0.301\
.NET workloads installed:
[ios]
Installation Source: VS 18.7.11903.348
Manifest Version: 26.5.10284/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.ios\26.5.10284\WorkloadManifest.json
Install Type: Msi
[android]
Installation Source: VS 18.7.11903.348
Manifest Version: 36.1.43/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.android\36.1.43\WorkloadManifest.json
Install Type: Msi
[maui-windows]
Installation Source: VS 18.7.11903.348
Manifest Version: 10.0.20/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maui\10.0.20\WorkloadManifest.json
Install Type: Msi
[maccatalyst]
Installation Source: VS 18.7.11903.348
Manifest Version: 26.5.10284/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maccatalyst\26.5.10284\WorkloadManifest.json
Install Type: Msi
Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.
Host:
Version: 10.0.11
Architecture: x64
Commit: e2f47b0110
.NET SDKs installed:
10.0.301 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 10.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 10.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 10.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.30 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 10.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 10.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
```
### IDE version
Visual Studio 2026 18.7.0
### Other details
https://github.com/dotnet/roslyn/pull/85162 fixes this
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the CA1704 unmeaningful-name check, especially the RemovePrefixIfPresent and IsWordNumeric logic described in the issue. Reproduce with the provided C# sample and verify that T1 and T2 produce no diagnostics while the existing spelling checks remain enabled; the issue notes that roslyn/pull/85162 already addresses it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100