Let's say I have the following code which update a field of a struct using reflection. Since the struct instance is copied into the DynamicUpdate method, it needs to be boxed to an object before being passed.

struct Person
{
    public int id;
}

class Test
{
    static void Main()
    {
        object person = RuntimeHelpers.GetObjectValue(new Person());
        DynamicUpdate(person);
        Console.WriteLine(((Person)person).id); // print 10
    }

    private static void DynamicUpdate(object o)
    {
        FieldInfo field = typeof(Person).GetField("id");
        field.SetValue(o, 10);
    }
}

The code works fine. Now, let's say I don't want to use reflection because it's slow. Instead, I want to generate some CIL directly modifying the id field and convert that CIL into a reusable delegate (say, using Dynamic Method feature). Specially, I want to replace the above code with s/t like this:

static void Main()
{
    var action = CreateSetIdDelegate(typeof(Person));
    object person = RuntimeHelpers.GetObjectValue(new Person());
    action(person, 10);
    Console.WriteLine(((Person)person).id); // print 10
}

private static Action<object, object> CreateSetIdDelegate(Type t)
{
    // build dynamic method and return delegate
}    

My question: is there any way to implement CreateSetIdDelegate excepts from using one of the following techniques?

  1. Generate CIL that invoke the setter using reflection (as the 1st code segment in this post). This makes no sense, given the requirement is to get rid of reflection, but it's a possible implementation so I just mention.
  2. Instead of using Action<object, object>, use a custom delegate whose signature is <
Edit
Report