Partial Class Accessibility Merging: Uncertain Permission Boundary
0 reputation · 10 May 2022, 03:09 UTC
0 reputation · 10 May 2022, 03:09 UTC
Ensure that all parts of a partial class share the same accessibility modifier so that an unintentional public exposure does not occur.
The current C# compiler (Roslyn) silently merges partial class parts, taking the most permissive modifier without any warning or error. This behavior can cause a type intended to be internal to become public if any part is declared public.
There is no documented compiler option or language feature that enforces uniform accessibility across partial class parts. Static analysis tools can detect mismatches, but they are not part of the language specification.
29275 reputation · 10 May 2022, 08:10 UTC
1. No compiler flag exists because the C# compiler already treats mismatched accessibility modifiers in partial class parts as a compile‑time error (CS0260). The compiler does not silently merge the parts; it refuses to build until all parts agree on the same modifier.
2. Roslyn analyzers can be configured to treat the mismatch as an error by elevating the analyzer’s diagnostic severity. The built‑in CS0260 diagnostic can be promoted via editorconfig or a custom analyzer that flags the same pattern and sets the severity to error.
3. No planned language change is documented that would alter the current rule. The C# specification (§10.2) explicitly requires identical accessibility for all partial type declarations, and this has been stable across releases.
Unlike some languages, C# enforces a single accessibility boundary for a type. If one part is public and another internal, the merged type would have an ambiguous visibility that could expose internal members to the outside world. The compiler therefore emits CS0260:
CS0260: Partial declarations of 'MyClass' must not specify different accessibility
To avoid this, all parts must use the same keyword (or omit it, which defaults to private and must match the others).
partial class MyClass.
private.
internal).
editorconfig. Add:
[*.cs]
dotnet_diagnostic.CS0260.severity = error
This guarantees the compiler treats the diagnostic as an error even if you later change the default severity.
If you prefer a linting experience that flags mismatches before compilation (e.g., in a CI pipeline), you can write a simple Roslyn analyzer that scans for partial declarations with differing accessibility. The analyzer can emit a diagnostic with severity error or warning as you wish.
If you encounter a build that succeeds despite mismatched modifiers, double‑check that you are using the latest .NET SDK and that no custom build step is altering the compiler flags. The behavior described above is standard in all recent releases (from .NET 5 onward).
Use comments to ask for clarification. Post a solution as an answer.
29,275 reputation · 10 May 2022, 12:24 UTC
In the default Roslyn configuration, the compiler merges partial class parts without emitting a warning or error when their accessibility modifiers differ; the resulting type takes the most permissive modifier (e.g., public overrides internal).
To catch such mismatches early, you can:
Error via an editorconfig entry or a ruleset.TreatWarningsAsErrors in the project file if you prefer to promote the analyzer’s warning to an error.This approach does not require a compiler flag and works with existing Roslyn versions.