Если вы хотите сделать это во всех нативных c # без каких-либо сторонних или «компонентных» внешних зависимостей, используйте CodeDomProvider
с крошечной начальной загрузкой JScript, например:
private static readonly MethodInfo eval = CodeDomProvider
.CreateProvider("JScript")
.CompileAssemblyFromSource(new CompilerParameters(), "package e{class v{public static function e(e:String):Object{return eval(e);}}}")
.CompiledAssembly
.GetType("e.v")
.GetMethod("e");
private static object JsEval(string jscript)
{
try
{
return eval.Invoke(null, new[] { jscript });
}
catch (Exception ex)
{
return ex;
}
}
, которая создает JsEval(string)
метод, который вы можете использовать в любом месте своего кода, чтобы «оценить» строку как JavaScript (ну, в общем, JScript) ... Итак, вызов:
MessageBox.Show("" + JsEval("2 + 2")); // 4
MessageBox.Show("" + JsEval("(function(){ return 3+7; })();")); // 10
MessageBox.Show("" + JsEval("function yay(a) { return a + 1; } yay(2);")); // 3
, в зависимости от вашего использования, вы можете не захотеть создавать экземпляры этих членовстатически.если вы хотите манипулировать сложными объектами, вам потребуется создать обертку для рефлексивного извлечения данных (или вы можете привести их в качестве соответствующего аналога JScript, но я никогда не пробовал этого, так как вам нужно было бы включать сборки JScript).
здесь приведен пример класса-обертки, который делает все, что JavaScript позволит вам делать изначально, добавление более высокоуровневой функциональности, вероятно, будет достаточно громоздким, так что вам будет лучше либо извлечь элементы в словарь /хеш-таблицу ИЛИ альтернативно сериализацию и десериализацию на другом конце
private class JsObjectWrapper : IEnumerable
{
public readonly object jsObject;
private static PropertyInfo itemAccessor = null;
private static MethodInfo getEnumerator = null;
public JsObjectWrapper(object jsObject)
{
this.jsObject = jsObject;
if (itemAccessor == null)
{
itemAccessor = jsObject.GetType().GetProperty("Item", new Type[] { typeof(string) });
}
if (getEnumerator == null)
{
getEnumerator = jsObject.GetType().GetInterface("IEnumerable").GetMethod("GetEnumerator");
}
}
public object this[string key]
{
get { return itemAccessor.GetValue(jsObject, new object[] { key }); }
set { itemAccessor.SetValue(jsObject, value, new object[] { key }); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)getEnumerator.Invoke(jsObject, null);
}
}
вы можете увидеть это в действии, выполнив следующее:
var jsObj = JsEval("var x = { a:7, b:9 };");
var csObj = new JsObjectWrapper(jsObj);
MessageBox.Show("a: " + csObj["a"]); // a: 7
MessageBox.Show("b: " + csObj["b"]); // b: 9
csObj["yay!"] = 69;
foreach (string key in csObj)
{
MessageBox.Show("" + key + ": " + csObj[key]); // "key": "value"
}
лично я использовал код, похожий на этот, для большого эффектав тот или иной момент он может поручиться за его доступность и работоспособность в серверной среде. Надеюсь, это поможет -ck