x


What are the Syntax Differences in C# and Javascript?

Although the Unity Scripting page gives an overview of the differences in C# versus Javascript, it isn't comprehensive. I have run into several places where a tutorial in Javascript had some code that didn't translate directly into C#, and I had to do some research to find the C# version. So what other syntax differences are in C# versus JS?

more ▼

asked Mar 11, 2010 at 04:53 PM

Cyclops gravatar image

Cyclops
8k 75 88 145

I think this question should be a community wiki.

Mar 12, 2010 at 09:39 PM Lipis

Uh, why? It doesn't even have a single up-vote... It's clearly useless, in fact I should probably delete it. :)

Actually, I've decided my next Question will be, "How to write an MMO for the iPhone while rotating an object/the camera around." It should get millions of votes...

Mar 14, 2010 at 03:12 PM Cyclops

I think it's a good question. I think it's just the answer which should be CW.

Mar 19, 2010 at 09:31 AM duck ♦♦

+1 @Cyclops Even though I don't like C#.. 600++ :)

Mar 20, 2010 at 07:53 PM Lipis

@Lipis - dude! heh... Really, it's not my favorite language either - Python is amazing. But for working with Unity, it just seems that C# is the best choice for me.

Mar 20, 2010 at 08:03 PM Cyclops
(comments are locked)
10|3000 characters needed characters left

6 answers: sort voted first

The purpose of this answer is to provide a single point of reference for the syntactical differences between C# and JS. It is mainly for people who have already made their decision as to which language to use, and might need to know the differences (for instance, to translate a script from one language to another).

If you want to know more about why you might choose one language over another in Unity, there are several other Questions - for instance: How should I Decide... C#/JS/Boo. And for performance issues, there is: Performance Difference... JS/C#?.

These are in addition to the differences listed in the Unity Manual page: Writing Scripts in C#.


Unity Script Directives

Unity has a number of Script Directives, for example, AddComponentMenu. The syntax is:

// Javascript example
@script AddComponentMenu ("Transform/Follow Transform")
class FollowTransform extends MonoBehaviour {
}  

// C# example:
[AddComponentMenu("Transform/Follow Transform")]
class FollowTransform : MonoBehaviour {
}

Type names

A couple of the basic types are spelt differently in pure Unity C#:

  • C#: bool, Javascript: boolean
  • C#: string, Javascript: String

However, if you include System in your C# script, you can also use .NET's String and Boolean class (note the upper-case):

using System;
String foo = "testing";
Boolean bar = false;

Variable declaration

Variable declaration is different, including access and type specification:

// C#: the type is always stated when declaring a variable:
public int myPublicInt = 1;      // a public var
int myPrivateInt = 2;            // **private** access is default, if access is unspecified
public GameObject myObj;         // a type is specified, but no value assigned

// Javascript - type specification is not necessary:
var myPublicInt = 1;             // **public** access is default, if unspecified
private var myPrivateInt = 2;    // a private var
var myObj : GameObject;          // a type is specified, but no value assigned (see below)

Variables with dynamic type resolution

In Javascript only, variables can have an unspecified type. This only occurs if you do not assign a value while declaring the variable. For example:

// Javascript:
var numBullets : int;  // statically typed (because type specified)
var numLivesLeft = 3;  // statically typed (because type is inferred from value assigned)
var player;            // dynamically typed (because neither a type or value is specified)

Performance is slower with dynamically typed variables, and you can run into casting problems. Iif this is a concern, use #pragma strict.


Multi-dimensional array declaration

Unity's Javascript support the syntax for declaring multi-dimensional built-in arrays. Eg:

// C#:
int[,] = new int[16,16];  // 16x16 2d int array

// Javascript:
var a = new int[16,16];

The performance of multi-dimensional arrays, at least in Javascript, is questioned.


Character literals not supported

Unity's Javascript seems to be missing the syntax to declare character literals. This means you need to get them implicitly by referencing a character index from a string. For example:

// C#
char myChar = 'a';

// Javascript:
var myChar = "a"[0];  // implicitly retrieves the first character of the string "a"

Class declarations

You can define classes in Javascript, in a similar way to C#. Here's an example of a class which inherits from MonoBehaviour

// Javascript example
class MyClass extends MonoBehaviour {

    var myVar = 1;

    function Start() {
        Debug.Log("hello world!");
    }
}  

// C# example:
class MyClass : MonoBehaviour {

    public int myVar = 1;

    void Start() {
        Debug.Log("hello world!");
    }
}

However in Javascript, if you're inheriting from MonoBehaviour, you don't need to write a class body at all (see the next section).

You can also write classes which do not inherit from anything, however you can't place scripts like this on Game Objects - you have to instantiate them with the 'new' keyword:

// Javascript example
class MyClass {

    var myVar = 1;

    // constructor:
    public function MyClass() {
        Debug.Log("hello world!");
    }
}  

// C# example:
class MyClass{

    public int myVar = 1;

    // constructor:
    public MyClass() {
        Debug.Log("hello world!");
    }
}

If you are inheriting from MonoBehaviour, you should not use constructors or destructors. Instead, use the Event handler functions "Start", "Awake" and "OnEnabled".


Implicit Class declarations

Unity's Javascript has a feature whereby if you do not declare any class body, it is automatically implemented for you. For example, a script which contains only variables and functions (and no explicit class declaration) is automatically implemented as:

// Your javascript is converted to (approximately)
class TheScriptName extends MonoBehaviour {
     ... your script here
}

This means that any Javascript script that you write without an explicit class body, automatically inherits from MonoBehaviour, and is therefore a component which can be attached to a GameObject (which is usually what you want!).


Limited interface support

While Unity's Javascript does support inheritance and interfaces, it has the very limiting caveat that you can either inherit your class from an existing class, or declare one interface. Eg:

// C#
class Apple : MonoBehaviour, ICollectable, IEatable, IThrowable { ... }

// Javascript - only one allowed:
class Apple extends CollectableObject { ... }

// or
class Apple extends IThrowable { ... }

Generics

The C# syntax supports "Generics" which allows you to use classes and methods which do not specifically declare a type. Instead, the type is passed as a parameter when calling the method or instantiating the class at runtime. These now work in both Unity and Unity iPhone (since v1.6).

.Net comes with some useful Generic classes such as the List and Dictionary, and Unity's own API has some generic functions which remove the need for some of the verbose casting which would otherwise be necessary in C#. For example:

// In Javascript, the "GetComponent" function returns an object, which is automatically cast by Javascript to the correct type
var someScript : ExampleScript = GetComponent(ExampleScript);

// In C#, without the Generic version of "GetComponent" we'd have to cast it ourselves (yuck):
ExampleScript someScript = (ExampleScript) GetComponent(typeof(ExampleScript));

// But instead, we can use the generic version provided by the Unity API, like this:
ExampleScript someScript = GetComponent<ExampleScript>();

// The generic version can also be used from JavaScript:
var someScript = GetComponent.<ExampleScript>();

For a more complete definition of Generics: MS Introduction to C# Generics


The Foreach keyword

C# Iterators use foreach instead of for. Also notice the variable declaration within the for/foreach statement. C# requires the type of the item contained in the list to be explicitly declared.

// Javascript
for (var item in someList) {
    item.DoSomething();
}

// C# 
foreach (ItemType item in someList)
{
    item.DoSomething();
}
Note though that the JavaScript version uses inefficient dynamic typing (since you *can't* declare the type). The static-typed alternative is:
// Javascript
for (var e=someList.GetEnumerator(); e.MoveNext();)
    e.Current.DoSomething();

The New keyword

In Javascript, you can create a new instance of an object or struct without using the 'new' keyword. In C#, using "new" is mandatory.

// Javascript:
var myPosition = Vector3(0,0,0);
var myInstance = MyClass(); // creates a new instance of script "MyClass".
var myTex = Texture2D(128,128); // creates a new texture2d object.

// C#
Vector3 myPosition = new Vector3(0,0,0);
MyClass myInstance = new MyClass();
Texture2D myTex = new Texture2D(128,128);

Yield in Unity C# versus Unity Javascript

Although Unity's documentation does (briefly) cover the syntax differences in using Yield at Writing C# Scripts(Step 4), there is also a Unity Answer that covers How do I Use Yield in C#, which has a more detailed explanation. In addition, the answer by equalsequals has a link to a Coroutine Tutorial that is worth checking out.


Unity's Yield has additional capabilities over .NET C# Yield

The above paragraph covered the differences in Unity's C# versus Javascript syntax. However, I think that it's worth explaining that the behavior of Unity's Yield statement (in both C# and Javascript), has some additional features not in Microsoft's .Net C# behavior.

Basically, Unity has added the YieldInstruction (and child classes such as WaitForSeconds) to Yield. These classes give Yield the ability to temporarily pause the function, until a condition is met. If it has zero parameters, it pauses for a single frame. If it has a parameter of WaitForSeconds:

yield return new WaitForSeconds (2.0f); // pauses for 2 seconds.

then it pauses for some number of seconds. If the parameter is another Coroutine, then it pauses until that Coroutine finishes.

Yield only works this way inside a Coroutine. To start a Coroutine in C#, you use StartCoroutine, whereas it is automatically called in Javascript.

For a good explanation of how Coroutines and the main routine interact, see Duck's Answer


Casting

Javascript automatically casts from one type to another, where possible. For example, the "Instantiate" command returns a type of "Object":

// in Javascript, there's no need to cast the result of "Instantiate" provided the variable's type is declared:
var newObject : GameObject = Instantiate(sourceObject);

// in C#, both the variable and the result of instantiate must be declared:
GameObject foo = (GameObject) Instantiate(sourceObject); // C#
GameObject foo = Instantiate(sourceObject) as GameObject; // C# second version

Also, see Murcho's answer for more information about casting, including why you would want to use the second casting method listed.


Properties with Getters/Setters

In C#, it is possible to define special functions that can be accessed as if they were variables. For instance, I could say foo.someVar = "testing";, and under the hood, there are get and set functions which process the argument "testing" and store it internally. But - they could also do any other processing on it, for instance, capitalizing the first letter before storing it. So you're not just doing a variable assignment, you're calling a function that sets the variable, and it can do - whatever functions do.

I'm not going into the syntax here, this answer is long enough :) But here are two links:
MS: Using Properties, and C# Properties Tutorial.


Changing struct properties / by value vs by reference

This is actually a bit more than a syntactical difference but nevertheless fits here quite well:

The following code does work in JavaScript/UnityScript but not in C#:

transform.position.x = 3;

The reason is because transform.position really is not just a public variable but a property, so it's actually returned by a method call - and that happens "by value" for structs (Vector3 is a struct and not a class - for performance reasons). So, to achieve the same in C#, you have to write:

Vector3 pos = transform.position;
pos.x = 3;
transform.position = pos;

While this may look more complicated (and less performant), it's exactly what also happens in UnityScript - only that in UnityScript, you don't see it.


Function/Method definitions

First of all, terminology - Javascript uses the term "Function", while C# calls these "Methods". They mean the same thing, and most C# coders understand the term "Function".

Javascript functions are declared with the keyword function before the function name. C# Method declarations just use the return type, and the method name. The return type is often "void" for common Unity events. Javascript functions are public by default, and you can specify them as private if required. C# methods are private by default, and you can specify that they should be public if required.

In Javascript, you can omit the parameter types and the return type from the declaration, but it's also possible to explicitly specify these (which is sometimes necessary if you run into type ambiguity problems).

Javascript function examples:

// a common Unity monobehaviour event handler:
function Start () { ...function body here... }

// a private function:
private function TakeDamage (amount) {
    energy -= amount;
}

// a public function with a return type.
// the paramter type is "Transform", and the return type is "int"
function GetDistanceTo (other : Transform) : int {
    return (transform.position - other.position).magnitude;
}

And the equivalent C# methods examples:

// a common Unity monobehaviour event handler:
void Start() { ...function body here... }

// a private function:
void TakeDamage(int amount) {
    energy -= amount;
}

// a public function with a return type.
// the parameter type is "Transform", and the return type is "int"
public int GetDistanceTo (Transform other) {
    return (transform.position - other.position).magnitude;
}

If you want to add any more answers to this question, please do so as an edit to this question (that's what community wiki answers are for).

more ▼

answered Mar 11, 2010 at 04:53 PM

Cyclops gravatar image

Cyclops
8k 75 88 145

and this answer should be a community wiki as well..

Mar 12, 2010 at 09:40 PM Lipis

But, but, I don't get any points for Wiki posts... :) Just kidding - consider it done. Since it's... done. I added a page to the Programming->General section.

Mar 12, 2010 at 11:30 PM Cyclops

Yeah yeah.. but this questions smells for wiki.. you had that in your mind I would guess before posting it.. :)

Mar 13, 2010 at 12:05 AM Lipis

@Lipis, when you said wiki, I thought you meant putting a post in the Unify Wiki. What exactly does it mean that this post is a Community Wiki? Who changes these things? And then there's the fact I don't get rep points for it any more...

Mar 14, 2010 at 11:36 PM Cyclops

bool is the same as Boolean. Like int is the same as Int32, float as Single and double as Double.

In Java primitive type and their object counterpart are different, but in C# this is all the same : the same IL assembly code is generated.

Apr 14, 2013 at 05:26 PM Kryptos
(comments are locked)
10|3000 characters needed characters left

I'd just like to add to the casting section, in C# there are two types of casts that produce different results when failed.

// These are both C#
GameObject go1 = (GameObject)Instantiate(prefab);
GameObject go2 = Instantiate(prefab) as GameObject;

If the return value of Instantiate() can't be cast to a GameObject, these two lines will produce very different results.

The first line will throw an exception, and if not handled correctly with a try catch statement can cause all kinds of issues.

The second line however is a much safer way to work. Using the as keyword for casting will return null if the return value of Instantiate() can't be cast to a GameObject. This is a very important difference as you can use this in a couple of ways. 1. It won't throw an exception, so a quick null test is all thats required. 2. Used in a different situation, it can be helpful for determining inheritance hierarchies.

E.G. Say you have a base Actor class, and you also create a Player class, a Monster1 class, and a Monster2 class that all inherit from the actor class. Every time you attack and hit something, you want to cause an effect to all actors, however each special actor type requires a different action. By using the as casting method, you can get through this very quickly.

void OnCollisionEnter(Collision collisionInfo)
{
    GameObject go = collisionInfo.gameObject;
    Actor actor = go.GetComponent<Actor>();
    if(actor = null)
        return;

    if(actor as Monster1 != null)
        // Do Monster1 attack damage

    if(actor as Monster2 != null)
        // Do Monster2 attack damage
}

Using the other casting method would cause all sorts of exceptions, and wouldn't actually make any sense here.

more ▼

answered Mar 13, 2010 at 12:12 AM

Murcho gravatar image

Murcho
2.9k 26 32 63

Cool, thanks, that's very good to know. I was aware of the other casting method, but didn't realize how differently its error-mode worked. I added the info about it to the wiki.

Mar 13, 2010 at 02:14 AM Cyclops

if(actor as Monster1 != null) If you're trying to do this, a better way is: if (actor is Monster1) Easier to read your intent, and works exactly the same way. Save "as" for when you actually want the value.

Sep 28, 2011 at 02:09 PM TSorbera
(comments are locked)
10|3000 characters needed characters left

as what you said it seems that you know C#. ok 1 js is a dynamic language so you don't need to cast returned data of functions like instantiate but you need to cast them in C#. 2 when using functions that have a parameter of type "type" like getComponent, you should pass the type of the data that you want. (typeof() or as keyword) 3 structures are passed by value in C# so you can not change the x or y value of a Vector3 and you need to create a new Vector3 and assign it to the Vector3 that you want. in js they write.

transform.position.x = 3;

in C# you should write

transform.position = new Vector3 (3,transform.position.y,transform.position.z);

the code is not slower because the js compiler do this itself. this code is not optimized. when you want to use things like transform much in Update or other functions that they run several times. store the result of transform in a variable and use that var instead of calling transform. for example

void Start ()
{
t = transform;
}

see the game optimization video of unite 07 for more info. transform or rigidbody or other variables like this will search for the Transform or Rigidbody component and it's not fast. so put them in class scope private vars and use them.

more ▼

answered Mar 11, 2010 at 06:22 PM

Ashkan_gc gravatar image

Ashkan_gc
10.1k 76 91 160

@Ashkan good catch on the iPhone 1.6, I didn't realize it had changed. The License page hasn't been updated with that fact. As for the rest, I'm not saying JS is slower than C#, there's already a Question about performance differences between languages. All I'm doing here is listing the syntax differences.

Mar 11, 2010 at 06:41 PM Cyclops

@Cyclops we should merge all good answers in one community answer..

Mar 12, 2010 at 09:41 PM Lipis

@cyclops many of the things that i wrote were syntax differences but as a programmer i always think and talk about performance. think of a guy that want to choose between languages and see this question and it's answers here. i love cyclops in X men. :)

Mar 13, 2010 at 05:13 AM Ashkan_gc

@Ashkan, actually I picked Cyclops from the Greek mythology, I never read the X-Men comic books (although of course I saw the movies). As to the performance, sure it's a factor, but again, I was trying to focus the Answer on syntax, as there are other Questions about performance. So this Answer is more for someone who has already decided to use C#, and needs to know how to convert the JS-based tutorials, for example.

Mar 13, 2010 at 03:00 PM Cyclops
(comments are locked)
10|3000 characters needed characters left
more ▼

answered Jun 21, 2013 at 12:56 AM

create3dgames gravatar image

create3dgames
717 26 33 44

(comments are locked)
10|3000 characters needed characters left

Who's the accepted answer was extremely helpful, thorough, and insiteful, the difference in syntax is irrelevant. If you can code in javascript you can easily learn c#. However c# is 100 times more powerful and I feel like anyone using javascript or boo is being lazy and cheating themselves out of unitys full potential

more ▼

answered Jun 21, 2013 at 01:48 AM

Slobdell gravatar image

Slobdell
1.4k 7 7 12

c# is 0% more powerful and 100% more inefficient, basically you have to write double the amount of code to achieve the same goal.. its a obsolete fetish like linux or macs..

Sep 30, 2013 at 05:59 PM jaxx0rr

For scripting maybe. Not for full fledged OOP. Javascript isn't even close

Sep 30, 2013 at 06:15 PM Slobdell
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x225
x128
x109
x86
x21

asked: Mar 11, 2010 at 04:53 PM

Seen: 79429 times

Last Updated: Feb 07 at 12:15 PM