Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.38 KB | None | 0 0
  1. using System.Linq.Expressions;
  2.  
  3. public static TDelegate CreateAccessor<TDelegate>(string memberName) where TDelegate : Delegate
  4. {
  5. var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
  6. if (invokeMethod == null)
  7. throw new InvalidOperationException($"{typeof(TDelegate)} signature could not be determined.");
  8.  
  9. var delegateParameters = invokeMethod.GetParameters();
  10. if (delegateParameters.Length != 1)
  11. throw new InvalidOperationException("Delegate must have a single parameter.");
  12.  
  13. var paramType = delegateParameters[0].ParameterType;
  14.  
  15. var objParam = Expression.Parameter(paramType, "obj");
  16. var memberExpr = Expression.PropertyOrField(objParam, memberName);
  17. Expression returnExpr = memberExpr;
  18. if (invokeMethod.ReturnType != memberExpr.Type)
  19. returnExpr = Expression.ConvertChecked(memberExpr, invokeMethod.ReturnType);
  20.  
  21. var lambda = Expression.Lambda<TDelegate>(returnExpr, $"Access{paramType.Name}_{memberName}", new [] { objParam });
  22. return lambda.Compile();
  23. }
  24.  
  25. ref struct Foo
  26. {
  27. private string A;
  28. private int B;
  29.  
  30. public Foo(string a, int b)
  31. {
  32. A = a;
  33. B = b;
  34. }
  35. }
  36.  
  37. delegate object FooAccessor(Foo foo);
  38. // or
  39. delegate T FooAccessor<T>(Foo foo);
  40.  
  41. var foo = new Foo("abc", 123);
  42. var a = CreateAccessor<FooAccessor<string>>("A")(foo);
  43. var b = CreateAccessor<FooAccessor<int>>("B")(foo);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement