dotnet / dotnet/runtime

Ignore return value of MethodBase.Invoke

Open
#119,933 4 comments 0 reactions 0 assignees View on GitHub
area-System.Reflection needs-further-triage
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Description

I'm trying to write high performance RPC library that minimizes allocations. It takes interface and generate stub, which reads arguments from stream, invokes required method, then passes return value to remote caller. In order to correctly pick method I use `MethodBase`, since it theoretically should have minimal method lookup time. The problem I have with this API is that there's no way to tell it not to box value types. Actual return value is handled by my code and stub always return `default(T)` which will be ignored.

I propose that `MethodBase.Invoke` should support `BindingFlags.IgnoreReturn`. If this flag is present, then runtime should skip boxing structs and may return classes.

### Reproduction Steps

Compile and execute following code:

code

```csharp
using System.Reflection;

public interface IAdder
{
int Add(int a, int b);
}

public sealed class Adder : IAdder
{
public int Add(int a, int b) => a + b;
}

public sealed class AdderDispatcher : IAdder
{
public int[] Args { get; set; } = new int[2];
public IAdder Impl { get; set; } = null!;
public Action ResultHandler { get; set; } = null!;

public int Add(int a, int b)
{
int result = Impl.Add(Args[0], Args[1]);
ResultHandler.Invoke(result);
return default;
}
}

public static class Program
{
public static void Main(string[] args)
{
var adder = new AdderDispatcher()
{
Args = [40, 2],
Impl = new Adder(),
ResultHandler = x => Console.WriteLine($"Print from callback {x}"),
};

var methodInfo = typeof(IAdder).GetMethod(nameof(IAdder.Add))!;
var emptyArgs = new object?[] { null, null };

var returnValue = methodInfo.Invoke(adder,
BindingFlags.DoNotWrapExceptions | BindingFlags.IgnoreReturn,
binder: null,
emptyArgs,
culture: null);
Console.WriteLine($"Return value is {returnValue ?? ""}");
}
}
```

### Expected behavior

Output is:
```
Print from callback 42
Return value is
```

### Actual behavior

Output is:
```
Print from callback 42
Return value is 0
```

### Regression?

No, it never worked before

### Known Workarounds

_No response_

### Configuration

SDK: 9.0.305
OS: Windows 11 24h2
Arch: x64

### Other information

I'm willing to implement fix for this

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.