Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Linq.Expressions;
- public static TDelegate CreateAccessor<TDelegate>(string memberName) where TDelegate : Delegate
- {
- var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
- if (invokeMethod == null)
- throw new InvalidOperationException($"{typeof(TDelegate)} signature could not be determined.");
- var delegateParameters = invokeMethod.GetParameters();
- if (delegateParameters.Length != 1)
- throw new InvalidOperationException("Delegate must have a single parameter.");
- var paramType = delegateParameters[0].ParameterType;
- var objParam = Expression.Parameter(paramType, "obj");
- var memberExpr = Expression.PropertyOrField(objParam, memberName);
- Expression returnExpr = memberExpr;
- if (invokeMethod.ReturnType != memberExpr.Type)
- returnExpr = Expression.ConvertChecked(memberExpr, invokeMethod.ReturnType);
- var lambda = Expression.Lambda<TDelegate>(returnExpr, $"Access{paramType.Name}_{memberName}", new [] { objParam });
- return lambda.Compile();
- }
- ref struct Foo
- {
- private string A;
- private int B;
- public Foo(string a, int b)
- {
- A = a;
- B = b;
- }
- }
- delegate object FooAccessor(Foo foo);
- // or
- delegate T FooAccessor<T>(Foo foo);
- var foo = new Foo("abc", 123);
- var a = CreateAccessor<FooAccessor<string>>("A")(foo);
- var b = CreateAccessor<FooAccessor<int>>("B")(foo);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement