0

我正在尝试将 javascript 对象发送到 c# 世界,但我无法弄清楚是如何完成的。

这是我的javascript代码

myClass.Do( 'str', { key : 'Testing' } );

我已经尝试在 c# 类上使用这些方法签名,第一个参数是正确的,但第二个参数始终为空。

public Do(string param1, object param2); // param1 = 'str', param2 = null
public Do(string param1, dynamic param2); // param1 = 'str', param2 = null
public Do(string param1, JsObject param2); // param1 = 'str', param2 = null
public Do(string param1, JsDictionary param2); // param1 = 'str', param2 = null
public Do(string param1, ArgumentClass param2); // param1 = 'str', param2 = null
public Do(string param1, object[] param2); // throws method not found

有没有办法做到这一点?

4

3 回答 3

0

我不得不在 Native\JsClr.cs 中修改这个方法

public static object ConvertParameter(JsInstance parameter)
{
    if (parameter.Class != JsFunction.TYPEOF && parameter.Class != JsArray.TYPEOF && parameter.Class != JsObject.TYPEOF)
    {
        return parameter.Value;
    }
    else if (parameter == JsNull.Instance)
    {
        return null;
    }
    else
    {
        JsFunction constructor = ((JsDictionaryObject)parameter)["constructor"] as JsFunction;
        if (constructor == null) return parameter;

        switch (constructor.Name)
        {
            case "Date":
                return JsDateConstructor.CreateDateTime(parameter.ToNumber());
            case "String":
            case "RegExp":
            case "Number":
                return parameter.Value;
            case "Array":
                object[] array = new object[((JsObject)parameter).Length];
                foreach (KeyValuePair<string, JsInstance> key in (JsObject)parameter)
                {
                    int index = 0;
                    if (int.TryParse(key.Key, out index))
                    {
                        array[index] = ConvertParameters(key.Value)[0];
                    }
                }
                return array;
            case "Object":

                if (parameter.Class == JsFunction.TYPEOF) return parameter;

                Dictionary<string, object> dic = new Dictionary<string, object>();
                foreach (KeyValuePair<string, JsInstance> key in (JsObject)parameter)
                {
                    dic.Add(key.Key, ConvertParameter(key.Value));
                }
                return dic;
            default:
                return parameter;
        }
    }

}

这是功能设置:

m_Engine = new JintEngine(Options.Ecmascript3);
m_Engine.SetFunction("Compute", new Jint.Delegates.Func<object, object>(JSCompute));

在该方法中,我将参数转换为 Dictionary 以获取值但返回构造的 JsObject。如果任何属性本身就是对象,您也可以将它们转换为 Dictionary:

public object JSCompute(object o)
{
    Dictionary<string, object> properties = (Dictionary<string, object>)o;
    double x = (int)((double)properties["X"]);
    double y = (int)((double)properties["Y"]);
    double width = (int)((double)properties["Width"]);
    double height = (int)((double)properties["Height"]);

    JsObject results = new JsObject();
    results["Area"] = new JsNumber(width * height);
    results["Diagonal"] = new JsNumber(Math.Sqrt(x * x + y * y));
    return results;
}

这是javascript:

var rectangle = { "X": 5, "Y": 10, "Width": 20, "Height": 10 };
var result = Compute(rectangle);
alert('Area is ' + result.Area + ', Diagonal is ' + result.Diagonal);
于 2010-09-17T11:36:52.140 回答
0

您发布的 JavaScript 代码无法解析。会不会是您的特定 JavaScript 解释器非常宽松,并将调用重新解释为myClass.Do('str')?那将解释空值。

于 2010-09-16T22:44:31.253 回答
0

在 .NET 4.0 中,指定第二个参数是dynamic,并且您应该获得可以使用的对象引用。在 3.5 及更低版本中,它将是某种 JsObject,但不应该直接使用整个 Microsoft.JScript 命名空间,所以我不太确定您是否可以指定您将使用 JsObject。

“key”应该是字符串文字还是另一个变量的名称?您还缺少关于“测试”的结束语。我严重怀疑 JS 是否会完全按照所写的那样正确编译。

于 2010-09-16T22:46:27.817 回答