might have noticed something odd about that last example using SetValue.
If you actually look up the method signature of SetValue in
the CLR documentation it notes that the function signature is:
function SetValue(value : Object, indices : int) : void
odd thing is the annotation on indices.
It is typed as taking a .NET array of integers but in the example in my last entry
we give it a literal JScript array, not a hard-typed CLR array.
.NET arrays and hard-typed CLR arrays work together, but because these two kinds of
arrays are so different they do not work together perfectly.
The problem is essentially that JScript .NET arrays are much more dynamic than CLR
arrays. JScript .NET arrays can change size, can have elements of any type, and so
rules for when JScript .NET arrays and CLR arrays may be used in place of each other
are not particularly complicated but still you should exercise caution when doing
so. In particular, when you use a JScript .NET array in a context where a CLR array
is expected you can get unexpected results. Consider this example:
ChangeArray(arr : int) : void
jsarr : Array = new Array(10, 20, 30);
// 10 or 110?
might look like it prints out 10 then 110, but in fact it prints out 10 twice. The
compiler is unable to turn the dynamic JScript array into a hard-typed array of integers
so it does the next best thing. It makes a copy of the JScript array and passes the
copy to the function. If the function reads the array then it gets the correct
values. If it writes it, then only the copy
is updated, not the original.
warn you about this possibly unintentional consequence of mixing array flavours, the
compiler issues the following warning if you do that:
JS1215: Converting a JScript Array to a System.Array results in a memory allocation
and an array copy
may now be wondering then why the call to SetValue which
had the literal JScript .NET array did not prompt this warning. The
warning is suppressed for literal arrays. In the case of literal arrays the compiler
can determine that a literal array is being assigned to a CLR array type. The
compiler then optimizes away the creation of the JScript .NET array and generates
code to create and initialize the CLR array directly. Since there is then no performance
impact or unexpected copy, there is no need for a warning.
that if every element of the source JScript .NET array cannot be coerced to the type
of the hard-typed CLR array then a type mismatch error will be the result. For instance,
if you tried to coerce an array containing strings to an array of integers then this
arr1 : int = new Array(10, “hello”, 20); // Type mismatch error at runtime
arr2 : int = [10, “hello”, 20]; //
Type mismatch error at compile time
also that this applies to multidimensional arrays. There
is no syntax for initializing a multidimensional array in JScript .NET:
mdarr : int[,] = [ [ 1, 2 ], [3, 4] ]; // Nice try, but illegal
A rectangular multidimensional
array is not an array of arrays. In this case you are assigning a one-dimensional
array which happens to contain arrays to a two-dimensional array of integers. That
is not a legal assignment. If, however, you want a ragged hard-typed
array it is perfectly legal to do this:
ragged : int = [ [ 1, 2 ], [3, 4] ];
multidimensional arrays are indexed with a comma-separated list inside one set of
square brackets. If you use ragged arrays to simulate true multidimensional arrays
then the indices each get their own set of brackets.
that JScript .NET arrays do not have any of the methods or properties of a CLR
array. (Strings, by contract, can be used implicitly as either JScript
.NET strings or as System.String values,
which I’ll talk more about later.) But
JScript .NET arrays do not have CLR
array fields like Rank, SetValue,
and so on.
time I’ll talk a bit about going the other way — using a CLR array where a JScript
array is expected.
You must be logged in to post a comment.
- Damit> Note that JScript .NET arrays do not have any of the methods or properties of a CLR array. (Strings, by contract, can be used implicitly as either JScript .NET strings or as System.String values, which I’ll talk more about later.) But JScript .NET arrays do not have CLR array fields like Rank, SetValue, and so on.Log in to Reply
- I wonder whether you meant to say here that JScript .NET arrays *have* CLR array fields? This paragraph sounds rather confusing to me…
- November 14, 2003 at 10:51 pm
for ( var i in a ) print(a[i] + ” “); // outputs 1 2 3 4
- var a = [1,2,3];
var l = a.list();
- a is now a Java array of integers (type [I…). You can also pass arguments to the toJava() method to control the type of array generated. The only upside of this technique when compared to what you did with JScript.NET is that it makes it clearer IMO that what you get is a copy of the original array.
- November 15, 2003 at 3:41 pm
- That’s a cool idea, but wouldn’t it be on the face of it easier to use Java as a unit testing platform for Java, rather than making Rhino interoperate better with Java? 🙂
- November 17, 2003 at 2:38 pm
- 3. If you look through the Rhino samples you’ll see that it’s also easier to create event handlers than in Java.
- 1. Rhino provides an interactive environment, so I can test classes interactively.
- Maybe, but it wouldn’t be as fun 😀
- November 18, 2003 at 4:26 am
- Log in to Reply
- Or for that matter instead of trying to hack code for .Net use sun’s ver of Java + IDE?
- July 23, 2004 at 1:44 pm
C# Scripting JScript VBScript Language Design COM Programming Rarefied Heights Puzzles Rants Performance Security C# 4.0 Non-computer SimpleScript JScript .NET Immutability Code Quality Pages Recursion Books