0

在 ASP.NET/C# 中:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
JavaScriptSerializer jss = new JavaScriptSerializer();
string[] fruits = new string[3] {"apple","banana","crunchberries"};
string output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

返回fruits=["apple","banana","crunchberries"]

在 ASP.NET/VB.NET 中:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
dim jss as new JavaScriptSerializer()
dim fruits  = new String(2) {"apple","banana","crunchberries"}
dim output as string =  jss.Serialize(fruits)
 %>
<html>
fruits=<%=output%>
</html>

返回fruits=["apple","banana","crunchberries"]

但在 ASP.NET/JScript.NET 中:

<%@ Page Language="JScript" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
var jss:JavaScriptSerializer = new JavaScriptSerializer;
var fruits = ["apple","banana","crunchberries"];
var output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

返回fruits=["0","1","2"]

这似乎完全被打破了。可以通过显式声明水果的数据类型来修复它,这使其成为“本机数组”:

<%@ Page Language="JScript" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
var jss:JavaScriptSerializer = new JavaScriptSerializer;
var fruits:String = ["apple","banana","crunchberries"];
var output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

返回fruits=["apple","banana","crunchberries"]

我不明白为什么要获得正确的序列化类型是强制性的。(var fruits = ["apple","banana","crunchberries",5]可能是糟糕的代码,但它在 Javascript 和 Jscript 中都是合法的。)假设 JScript 数组比本机数组慢,但它们仍然可以工作,对吧?

4

2 回答 2

1

看起来像一个类型推断问题 - 即可能 JScript.NET 被解释["apple","banana","crunchberries"]为整数数组。

您可以尝试创建一个函数,该函数采用 anobject和 cal 而不是JavaScriptSerializer.Serialize. 检查传入的值以查看它是什么。

于 2010-07-15T04:14:09.210 回答
0

我一直在指责 JavaScriptSerializer,但这个问题似乎与 JScript 对“JScript”数据类型与“.NET Framework”数据类型的人格分裂症有关。

首先,JavaScriptSerializer 的免责。它可以处理数组中的混合数据类型,如以下 VB 示例所示:

dim a as string = "apple"
dim b as int32 = 5
dim c as double = 22.22222
dim fruits(2) as  Object
fruits(0) = a
fruits(1) = b
fruits(2) = c
dim output as string =  jss.Serialize(fruits)

这返回["apple",5,22.22222],这是正确的。将此代码移植到 JScript(包含标量的显式类型声明和长度为 3 的 Framework 对象数组的实例化)也给出了正确答案:

var a:String="apple";
var b:Int32=5;
var c:Double=22.2;
var fruits:Object = new Object[3];
fruits[0]=a;
fruits[1]=b;
fruits[2]=c;
var output = jss.Serialize(fruits);

但是没有人那样写 Javascript。相反,您将使用以下方法编写一个灵活类型的堆栈:

var fruits = new Array();
fruits.push("apple");
fruits.push(5);
fruits.push(22.22222);

它使用 JScript“expando”数组对象。只要您留在 JScript 上下文中就可以了,但是在框架中调用任何东西都是自找麻烦。

这里的核心问题是 JScript 未能根据需要将 JScript 对象转换为框架 (CLR) 数组和对象。JScript 10.0 Array Object讨论中对此有一些警告。(“因此,在对符合 CLS 的方法的参数和返回类型进行类型注释时,请确保使用 System.Array 数据类型而不是 Array 对象。”)哇,我很高兴 JScript 编译器正在寻找为了我!

在这里很难说 JScript.NET 有什么好处。拥有一个包含两种微妙不同类型的数组和两种微妙不同类型的对象的环境似乎是自找麻烦。奇怪的是,Visual C# 2010 刚刚引入了“动态”类型和可以在新的“DLR”运行时下执行的 Expando 对象,因此现在可能可以制作一个不那么古怪的 JScript 版本。

于 2010-07-15T15:35:10.980 回答