Skip to content

Commit 6458310

Browse files
authored
[Mono] Fix ParameterInfo.Name to return null for unnamed parameters (#121105)
# [Mono] Fix ParameterInfo.Name to return null for unnamed parameters ## Summary Fixes runtime inconsistency where Mono's `ParameterInfo.Name` returns empty string (`""`) for unnamed parameters while CoreCLR correctly returns `null`. ## Problem **Failing Tests:** - `OpenApiOperationGeneratorTests.ThrowsInvalidOperationExceptionGivenUnnamedParameter` - `RequestDelegateFactoryTests.CreateThrowsInvalidOperationExceptionGivenUnnamedArgument` **Root Cause:** ```csharp // CoreCLR behavior (correct) var param = lambda.Compile().Method.GetParameters()[0]; param.Name == null // true // Mono behavior (bug) param.Name == "" // empty string, not null ``` ASP.NET Core validation checks `if (parameter.Name is null)` - this works on CoreCLR but fails on Mono. ## Reproduction ```csharp using System; using System.Linq.Expressions; var unnamed = Expression.Parameter(typeof(int)); var lambda = Expression.Lambda(Expression.Block(), unnamed); var param = lambda.Compile().Method.GetParameters()[0]; // CoreCLR: param.Name is null // Mono: param.Name is "" Console.WriteLine($"Name is null: {param.Name is null}"); ``` **Test Results:** - With only `loader.c` fix: `param.Name` still returns `""` - With both fixes: `param.Name` correctly returns `null` ### Why `ParameterInfo.Name` is nullable (`string?`) per [API Contract](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.parameterinfo.name?view=net-9.0&viewFallbackFrom=net-9.0)) ## Related Issues Fixes failures in dotnet/aspnetcore test suite when running on Mono runtime. cc: @giritrivedi
1 parent 4defc8b commit 6458310

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

src/mono/mono/component/debugger-agent.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9324,7 +9324,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
93249324
names = g_new (char *, sig->param_count);
93259325
mono_method_get_param_names_internal (method, (const char **) names);
93269326
for (guint16 i = 0; i < sig->param_count; ++i)
9327-
buffer_add_string (buf, names [i]);
9327+
buffer_add_string (buf, names [i] ? names [i] : "");
93289328
g_free (names);
93299329

93309330
break;

src/mono/mono/metadata/loader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,7 @@ mono_method_get_param_names_internal (MonoMethod *method, const char **names)
14461446
return;
14471447

14481448
for (i = 0; i < signature->param_count; ++i)
1449-
names [i] = "";
1449+
names [i] = NULL;
14501450

14511451
klass = method->klass;
14521452
if (m_class_get_rank (klass))

src/mono/mono/metadata/reflection.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,8 +1017,13 @@ add_parameter_object_to_array (MonoMethod *method, MonoObjectHandle member, int
10171017
goto_if_nok (error, leave);
10181018

10191019
MonoStringHandle name_str;
1020-
name_str = mono_string_new_handle (name, error);
1021-
goto_if_nok (error, leave);
1020+
if (name != NULL) {
1021+
name_str = mono_string_new_handle (name, error);
1022+
goto_if_nok (error, leave);
1023+
} else {
1024+
// Keep NULL as NULL instead of converting to empty string
1025+
name_str = MONO_HANDLE_NEW (MonoString, NULL);
1026+
}
10221027

10231028
MonoObjectHandle def_value;
10241029

src/mono/mono/mini/dwarfwriter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
18651865

18661866
emit_uleb128 (w, need_loclist ? ABBREV_PARAM_LOCLIST : ABBREV_PARAM);
18671867
/* name */
1868-
if (pname[0] == '\0') {
1868+
if (!pname || pname[0] == '\0') {
18691869
sprintf (pname_buf, "param%d", i - sig->hasthis);
18701870
pname = pname_buf;
18711871
}

0 commit comments

Comments
 (0)