Issue Description
When a .cs file contains a top-level record type (e.g. public record Person(string Name);) and an embedded resource is included in the project, MSBuild's CreateCSharpManifestResourceName does not correctly identify the record as a type declaration. This leads to incorrect or missing manifest resource naming, breaking embedded resource association and potentially satellite assembly localization. The parser looks for class/struct/enum/interface only, not record.
Steps to Reproduce
- Create a C# file with a
record type at the top (and optionally other types below):
public record Person(string Name);
public static class Extensions { /* ... */ }
- Add an embedded resource (e.g. .resx) to the same project.
- Build the project with MSBuild.
- Observe the generated manifest resource names in the build output and/or inspect satellite assemblies.
Expected Behavior
MSBuild should recognize record declarations in C# source files as top-level types, just like class/struct/enum/interface. Manifest resource names for embedded resources should be mapped as expected, enabling correct resource lookup and satellite assemblies.
Actual Behavior
Resources in files with a top-level record are not associated with the expected manifest resource names. This can cause runtime lookup failures and broken localization in assemblies using C# 9+ record types.
Analysis
The bug appears to be in CreateCSharpManifestResourceName, which calls CSharpParserUtilities.GetFirstClassNameFullyQualified(binaryStream). That parser only looks for class, struct, enum, or interface keywords, and skips record (added in C# 9). Updating the parser to also include record would resolve the issue.
Reference:
Versions & Configurations
dotnet msbuild -version
18.0.6.57005
Issue Description
When a .cs file contains a top-level
recordtype (e.g.public record Person(string Name);) and an embedded resource is included in the project, MSBuild'sCreateCSharpManifestResourceNamedoes not correctly identify therecordas a type declaration. This leads to incorrect or missing manifest resource naming, breaking embedded resource association and potentially satellite assembly localization. The parser looks for class/struct/enum/interface only, not record.Steps to Reproduce
recordtype at the top (and optionally other types below):Expected Behavior
MSBuild should recognize
recorddeclarations in C# source files as top-level types, just like class/struct/enum/interface. Manifest resource names for embedded resources should be mapped as expected, enabling correct resource lookup and satellite assemblies.Actual Behavior
Resources in files with a top-level record are not associated with the expected manifest resource names. This can cause runtime lookup failures and broken localization in assemblies using C# 9+ record types.
Analysis
The bug appears to be in
CreateCSharpManifestResourceName, which callsCSharpParserUtilities.GetFirstClassNameFullyQualified(binaryStream). That parser only looks for class, struct, enum, or interface keywords, and skipsrecord(added in C# 9). Updating the parser to also includerecordwould resolve the issue.Reference:
Versions & Configurations
dotnet msbuild -version
18.0.6.57005