Serializable (JSON) Types

The Saltarelle type system (as well as all other type system built in JavaScript), requires objects to be constructed using the ‘new’ operator, so their prototype chain is correctly set up. This creates a problem whenever an object is aquired through some other mechanism, often with serialization involved.

To alleviate this problem, Saltarelle supports serializable types. Serializable types are types that are either decorated with a [System.SerializableAttribute], or inherit from System.Record (Script# calls this record types).

Serializable types have these characteristics:

  • Constructors for them are normal static methods that return the created object, without using the JavaScript new operator at the call site.
  • All instance properties are treated as fields.
  • All instance methods are converted to static methods that receive the instance as their first argument.
  • They may not implement any interfaces.
  • They must inherit from either Object, System.Record or another serializable type.
  • They cannot contain virtual members.
  • Invoking their GetType() method will return Object.
  • All instance property/field names are preserved (but camel-cased), as if they were decorated with a [PreserveNameAttribute].

Serializable Dictionary

if you want to serialize a dictionary-like object you should use either of the types System.Collections.Generic.JsDictionary or System.Collections.JsDictionary.

Example

This C# source:

[Serializable]
public sealed class MySerializableType {
	public int IntProperty { get; set; }
	public string StringProperty { get; set; }
	public string GetDescription() {
		return IntProperty + " " + StringProperty;
	}
	public MySerializableType(int i, string s) {
		IntProperty = i;
		StringProperty = s;
	}
}
public class Driver {
	public void Main() {
		var o = new MySerializableType(10, "Some value");
		string s = o.GetDescription();
		Document.Instance.GetElementById("output").InnerText = s;
	}
} 

will be translated to this script:

MySerializableType = function() {
};
MySerializableType.getDescription = function($this) {
	return $this.intProperty + ' ' + $this.stringProperty;
};
MySerializableType.$ctor = function(i, s) {
	var $this = {};
	$this.intProperty = 0;
	$this.stringProperty = null;
	$this.intProperty = i;
	$this.stringProperty = s;
	return $this;
};
Driver = function() {
};
Driver.prototype = {
	main: function() {
		var o = MySerializableType.$ctor(10, 'Some value');
		var s = MySerializableType.getDescription(o);
		(document).getElementById('output').innerText = s;
	}
};