自己很喜欢JScript,因为觉得她很灵活,不过在.NET中的运用却很少,而且不知道是否是因为性能等方面的原因,JScript在.NET的众多语言中,运用得很少,网上讨论这方面的例子也很少。
今天同事遇到了个问题:代码是动态的,但却有很多,不过都是些判断语句、比较语句等;最初考虑用动态程序集的方式来创建,不过虽然那些动态代码都是些公式之类的,但是却有很多,多达上百条,所以这样实现起来很麻烦;于是想到了Javascript中的这个函数eval,进而想到了JScript。
新建一个脚本文件:
import System;
package myTest
{
public class Test
{
//计算
function Calculate(expression:String):Object
{
var o:Object=null;
eval("o="+expression+";");
return o;
}
}
}
这里的Calculate方法就是根据表达式进行计算返回值
通过下面的代码编译(注意:需先将环境变量Path设置为对应的.net版本比如我这里设置的2.0的C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727)
jsc /out:"C:\Documents and Settings\Administrator\桌面\JScript1.dll" /lib:"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727" "C:\Documents and Settings\Administrator\桌面\JScript1.js"
这样既可以得到一个生成的dll
用Reflector打开可以看到这个类的C#版本的代码:
在命名空间myTest下
[Serializable]
public class Test : INeedEngine
{
// Fields
[NonSerialized]
private VsaEngine vsa Engine;
// Methods
public Test()
{
this..init();
}
private void .init()
{
}
[JSFunction(JSFunctionAttributeEnum.HasStackFrame)]
public virtual object Calculate(string expression)
{
object obj3;
JSLocalField[] fields = new JSLocalField[] { new JSLocalField("expression", typeof(string).TypeHandle, 0), new JSLocalField("o", typeof(object).TypeHandle, 1), new JSLocalField("return value", typeof(object).TypeHandle, 2) };
StackFrame.PushStackFrameForMethod(this, fields, ((INeedEngine) this).GetEngine());
try
{
object obj2 = DBNull.Value;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[0] = expression;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[1] = obj2;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[2] = obj3;
object[] localVars = ((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars;
Eval.JScriptEvaluate("o=" + expression + ";", null, ((INeedEngine) this).GetEngine());
expression = Convert.ToString(((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[0], true);
obj2 = ((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[1];
obj3 = ((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[2];
object[] objArray2 = ((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars;
obj3 = obj2;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[0] = expression;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[1] = obj2;
((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars[2] = obj3;
object[] objArray3 = ((StackFrame) ((INeedEngine) this).GetEngine().ScriptObjectStackTop()).localVars;
}
finally
{
((INeedEngine) this).GetEngine().PopScriptObject();
}
return obj3;
}
private VsaEngine GetEngine()
{
if (this.vsa Engine == null)
{
this.vsa Engine = VsaEngine.CreateEngine();
}
return this.vsa Engine;
}
private void SetEngine(VsaEngine engine1)
{
this.vsa Engine = engine1;
}
}
新建了个c#的项目对这个dll添加引用进行测试
代码如下(项目中应该添加对Microsoft.Jscript.dll的引用哈)
myTest.Test test = new myTest.Test();
Console.WriteLine(test.Calculate("9+(2*1000)"));
string f = @"'hahahahdww;r;rrrr';";
Console.WriteLine(test.Calculate(f));
Console.ReadLine();
控制台输出:
2009
hahahahdww;r;rrrr
对于Jscript.NET的性能到底如何 尚未做测试