dotnet / dotnet/runtime

[API Proposal]: Add FieldInfo.CreateDelegate

Open
#128,206 11 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-System.Reflection
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Background and motivation

`MethodInfo.CreateDelegate` is a really useful method to get a fast method invoke function for methods obtained by reflection. I miss the same method on FieldInfo. On FieldInfo, the delegate would have to return a ref to the field to be valid.

### API Proposal

```c#
namespace System.Reflection;

// Current
// public abstract class MethodInfo : MethodBase
// {
// public virtual Delegate CreateDelegate(Type delegateType);
// public virtual Delegate CreateDelegate(Type delegateType, object? target);
// public T CreateDelegate() where T : Delegate;
// public T CreateDelegate(object? target) where T : Delegate;
// }

// Proposed
public abstract partial class FieldInfo : MemberInfo
{
public virtual Delegate CreateDelegate(Type delegateType);
public virtual Delegate CreateDelegate(Type delegateType, object? target);
public T CreateDelegate() where T : Delegate;
public T CreateDelegate(object? target) where T : Delegate;
}
```

### API Usage

```c#
static class B
{
private string _foo;
}

static class C
{
private static FieldInfo _fieldInfo = typeof(B).GetField("_foo", BindingFlags.NonPublic | BindingFlags.Instance)!;
private static FooDelegate _fieldAccessor = _fieldInfo.CreateDelegate();

// Use _fieldAccessor repeatedly to access the field value (or set it to a new value)
// without the overhead of reflection after the initial delegate creation.

private delegate ref string FooDelegate(B b);
}
```

### Alternative Designs

I have thought of an alternative for certain use cases, where we only need to get the value of a single object (when we get a closed delegate to a given target, as opposed to an open one). We could get a `ref` to the value and then reuse it as much as we like.
```c#
public abstract partial class FieldInfo : MemberInfo
{
// Existing
// public abstract object? GetValue(object? obj);
// public virtual object? GetValueDirect(TypedReference obj);

// Proposed
public abstract ref T GetValueRef(object? obj);
public virtual ref T GetValueRefDirect(TypedReference obj);
}
````

### Risks

I don't know any

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.