System.Linq.Dynamic: Как гарантировать порядок параметров в функции Parse? - PullRequest
0 голосов
/ 04 июня 2018

В приведенном ниже коде я успешно использую 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;
...