JS++ has a default ‘toString’ method implementation but, sometimes, it is necessary to override this implementation. For example, when using Console.log
, it may be desirable to be able to fully log and inspect a complex JS++ object.
In addition to the Unified External Type, there is also a “Unified Internal Type”: System.Object. All JS++ classes, including user-defined classes, inherit from System.Object. Due to auto-boxing, even primitive types such as int
(wrapped by System.Integer32
), inherit from System.Object
.
Aside: Don’t worry about the performance implications of auto-boxing. JS++ is able to optimize auto-boxing to the point that
toString
is actually 7.2% faster in JS++ than JavaScript in the worst case (assuming the JavaScript variable is monomorphically-typed) and more than 50% faster for polymorphically-typed (and potentially type-unsafe) JavaScript variables as shown in benchmarks here.
System.Object has a toString method which is marked as virtual
. In other words, this method can be overridden by derived classes – which are effectively all classes in JS++. Here’s an example of how to do it:
import System; class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; } override string toString() { return "(" + x.toString() + ", " + y.toString() + ")"; } } Point p = new Point(1,2); Console.log(p); // "(1, 2)"
You’ll notice the Console.log
statement doesn’t even make an explicit toString
call. The reason is because passing any JS++ object to Console.log
will call the toString
method on the object for you.