Is there a way to create a delegate to get and set values for a FieldInfo?

c#, delegates, expression-trees, fieldinfo, setvalue

Solution

Field access isn't performed via a method (like getters and setters)--it's performed with an IL instruction--so there's nothing you can assign to a delegate. you'll have to use the expression route to create a "block" of code (effectively IL) that can be assigned to a delegate.

Problem

For properties there are `GetGetMethod` and `GetSetMethod` so that I can do: ``` Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>), propertyInfo.GetGetMethod()); ``` and ``` Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>), propertyInfo.GetSetMethod()); ``` But how do I go about `FieldInfo`s? I am not looking for delegates to `GetValue` and `SetValue` (which means I will be invoking reflection each time) ``` Getter = s => (T)fieldInfo.GetValue(s); Setter = (s, t) => (T)fieldInfo.SetValue(s, t); ``` but if there is a `CreateDelegate` approach here? I mean since assignments return a value, can I treat assignments like a method? If so is there a `MethodInfo` handle for it? In other words how do I pass the right `MethodInfo` of setting and getting a value from a member field to `CreateDelegate` method so that I get a delegate back with which I can read and write to fields directly? ``` Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>), fieldInfo.??); Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>), fieldInfo.??); ``` I can build expression and compile it, but I am looking for something simpler. In the end I don't mind going the expression route if there is no answer for the asked question, as shown below: ``` var instExp = Expression.Parameter(typeof(S)); var fieldExp = Expression.Field(instExp, fieldInfo); Getter = Expression.Lambda<Func<S, T>>(fieldExp, instExp).Compile(); if (!fieldInfo.IsInitOnly) { var valueExp = Expression.Parameter(typeof(T)); Setter = Expression.Lambda<Action<S, T>>(Expression.Assign(fieldExp, valueExp), instExp, valueExp).Compile(); } ``` Or am I after the nonexistent (since I have nowhere seen something like that yet) ?

Original source

Related problems