Skip to content

Invoke with 'null' arg doesn't work when the target arg is a Nullable byref #67269

@steveharter

Description

@steveharter

Description

The new tests being added in #66357 don't pass on Mono:

    System.Reflection.Tests.MethodInfoTests.InvokeNullableRefs [FAIL]
      Assert.IsType() Failure
      Expected: System.Int32
      Actual:   (null)
      Stack Trace:
        /home/steve/git/runtimeReflection_2/src/libraries/System.Reflection/tests/MethodInfoTests.cs(640,0): at System.Reflection.Tests.MethodInfoTests.InvokeNullableRefs()
        /home/steve/git/runtimeReflection_2/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs(386,0): at System.Reflection.RuntimeMethodInfo.InvokeWorker(Object obj, BindingFlags invokeAttr, Span`1 parameters)


    System.Reflection.Tests.MethodInfoTests.InvokeBoxedNullableRefs [FAIL]
      Assert.IsType() Failure
      Expected: System.Int32
      Actual:   (null)
      Stack Trace:
        /home/steve/git/runtimeReflection_2/src/libraries/System.Reflection/tests/MethodInfoTests.cs(674,0): at System.Reflection.Tests.MethodInfoTests.InvokeBoxedNullableRefs()
        /home/steve/git/runtimeReflection_2/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs(386,0): at System.Reflection.RuntimeMethodInfo.InvokeWorker(Object obj, BindingFlags invokeAttr, Span`1 parameters)

Reproduction Steps

One of the test failures:

  int? iNull = null;
  object[] args = new object[] { iNull, 10 };
  Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullToValue)).Invoke(null, args));
  Assert.IsType<int>(args[0]); // Fails here - type and value are null
  Assert.Equal(10, (int)args[0]);
  
  static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod(
      name, BindingFlags.Public | BindingFlags.Static)!;

  public static class NullableRefMethods
  {
      public static bool NullToValue(ref int? i, int value)
      {
          Assert.Null(i);
          i = value;
          return true;
      }
  }

Expected behavior

If this feature is to be supported to match CoreClr, a null values should indicate to create a default value; int32 in this case. That value is allowed to be passed by-ref, modified, and then the original object[] updated to reflect that.

Actual behavior

When null is passed to a method that takes a Nullable<T> by reference, null is always returned.

Regression?

No

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions