System.Linq.Dynamic: Как гарантировать порядок параметров в функции Parse?
В приведенном ниже коде я успешно использую Microsoft System.Linq.Dynamic в C# для оценки строковых выражений, похожих на Javascript eval()
, Однако я не могу понять, как гарантировать совпадение имен параметров и соответствующих значений при вызове новой функции. "SKU + \" \" + Name"
мог вернуться 1234 Cola
так же легко, как Cola 1234
, У меня есть десятки параметров.
System.Dynamic.Linq-х Parse
метод использует Dictionary<string,object>
хранить параметры внутри, что является моей проблемой, потому что Словарь не гарантирует порядок, как массивы и списки. Я предполагаю, что, поскольку Microsoft решила использовать Словарь, должно быть какое-то простое исправление кода ниже, чтобы обеспечить совпадение значений параметров. Код был введен в LinqPad.
Именованные параметры возможны как Name: "Cola", SKU: "1234"
? Есть ли какой-либо тип данных или метод, который я мог бы использовать, чтобы гарантировать совпадение имен параметров и значений? Требуется ли изменение кода Microsoft для замены словаря?
var symbols = new Dictionary<String, Object>(); // Cannot change symbols datatype
var paramExp = new List<ParameterExpression>();
var paramVal = new List<String>();
var fields = new Dictionary<String,String>(); // Sample Data
fields["SKU"] = "1234";
fields["Name"] = "Cola";
fields["Type"] = "Drink";
var expression = "SKU + \" \" + Name";
foreach( var f in fields) { // Setup Parameters
ParameterExpression x =
Expression.Parameter(Type.GetType("System.String"), f.Key);
symbols.Add( f.Key, x);
paramExp.Add( x);
paramVal.Add( f.Value);
}
Expression body = System.Linq.Dynamic.DynamicExpression.Parse(
Type.GetType("System.String"), expression, symbols);
LambdaExpression e = Expression.Lambda(body,
paramExp.ToArray()); // Order may not match body
var c = e.Compile();
c.DynamicInvoke(paramVal.ToArray()); // Same here ... possible order mismatch
// c.Dump(); // outputs "1234 Cola"
Вот примеры использования выше и System.Linq.Dynamic:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Linq.Dynamic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;