Potrzebuję utworzyć System.Linq.Expressions.Expression
, który wywołuje dynamiczny obiekt. Obiektem dynamicznym może być ExpandoObject
lub dowolny inny.Prawidłowy sposób konstruowania wyrażenia .NET do wywoływania obiektów dynamicznych
Rozważmy następujący test:
var myInstance = DateTime.Now;
var methodInfo = myInstance.GetType().GetMethod("ToUniversalTime");
var methodCallExpression = Expression.Call(Expression.Constant(myInstance), methodInfo);
var expression = Expression.Lambda(methodCallExpression);
Assert.AreEqual(myInstance.ToUniversalTime(), expression.Compile().DynamicInvoke());
muszę stworzyć odpowiednik wyraz podczas myInstance deklaruje podobne (tylko jako przykład):
dynamic myInstance = new ExpandoObject();
myInstance.MyMethod = new Func<string>(() => "hello world");
Przypuszczam, że muszę korzystać Expression.Dynamic
metoda (patrz MSDN). Ale nie wiem, jak z niego korzystać. Próbowałem szukać na google, ale tylko przykłady, które znalazłem użyć klasy Microsoft.CSharp.RuntimeBinder.Binder
(patrz MSDN), które nie mogą być oficjalnie używany:
Ten interfejs API obsługuje infrastrukturę programu .NET Framework i nie jest przeznaczony do stosowania bezpośrednio z Twojego kodu.
Korzystanie Microsoft.CSharp.RuntimeBinder.Binder
mogę napisać poniższy kod:
dynamic myInstance = new ExpandoObject();
myInstance.MyMethod = new Func<string>(() => "hello world");
var binder = Binder.InvokeMember(
CSharpBinderFlags.None,
"MyMethod",
null,
this.GetType(),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant, null) });
var methodCallExpression = Expression.Dynamic(binder, typeof(object), Expression.Constant(myInstance));
var expression = Expression.Lambda(methodCallExpression);
Assert.AreEqual(myInstance.MyMethod(), expression.Compile().DynamicInvoke());
Jest to rozwiązanie prawidłowe?
Tak, tak to zaimplementowałem w CSharpEval – EnderWiggin