Picking up from last time, today we’ll finish off classes in C# from an AS3 perspective in preparation for next week when we delve into all-new concepts that aren’t in AS3 at all. Read on to learn the C# way to implement getters and setters, final functions and classes, const variables, and packages.

Table of Contents

First up are getters and setters. As a refresher, here’s how they look in AS3:

class Person
{
    private var _name:String;
    public function get name(): String
    {
        return _name;
    }
    public function set name(n:String): void
    {
        _name = n;
    }
}

Now let’s see the equivalent code in C#:

class Person
{
    private String _name;
    public String Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
}

Instead of being declared as two functions, the getter and setter are declared as a single variable. That variable doesn’t end with a semicolon (;) but instead a curly braces block containing to parts: get{} and set{}. Those parts are the getter and setter functions. Inside the setter you get access to a new keyword: value. This means “the value to set” because you never declared it as a parameter, unlike AS3. Other than this syntactical difference, everything else works the same.

C# also provides a shorthand to avoid most of this typing for simple getters and setters. Behold:

class Person
{
    public String Name { get; set; }
}

Using this will automatically create the _name variable and the getter and setter functions just as they were in the previous example. But what if you didn’t want a setter? Just leave it out:

class Person
{
    public String Name { get; }
}

However, you probably want at least the Person class to be able to set it. In that case, just declare it private:

class Person
{
    public String Name { get; private set; }
}

Finally, one bit of terminology. The field of the class that does the getting and/or setting (Name) is called a “property” in C# lingo. The variable it gets and sets (_name) is called the “backing field”.

Next let’s talk about “final” functions that can’t be overridden.

class Person
{
    final function print(): void
    {
        trace("I'm a Person");
    }
}
 
class MyPerson extends Person
{
    // illegal
    override function print(): void
    {
        trace("I'm not just a Person, I'm a MyPerson too");
    }
}

C# has the same concept with its sealed keyword again:

class Person
{
    sealed void Print()
    {
        Debug.Log("I'm a Person");
    }
}
 
class MyPerson : Person
{
    // illegal
    override void Print()
    {
        Debug.Log("I'm not just a Person, I'm a MyPerson too");
    }
}

Now on to packages in AS3:

package com.jacksondunstan.examples
{
    class Person
    {
    }
}

C# simply calls a package a namespace instead:

namespace com.jacksondunstan.examples
{
    class Person
    {
    }
}

To give access to the classes in a package to a .as file, you import the package:

import com.jacksondunstan.examples;
 
class Printer
{
    function print(person:Person): void
    {
        trace("person has name: " + person.name);
    }
}

In C#, you say that you’re using the namespace:

using com.jacksondunstan.examples;
 
class Printer
{
    void Print(Person person)
    {
        Debug.Log("person has name: " + person.name);
    }
}

Finally today, let’s talk about const fields in AS3. This is how you make a field that can’t be changed after it’s declared:

class Person
{
    private static const MIN_TEEN_AGE:int = 13;
    private static const MAX_TEEN_AGE:int = 19;
    var age:int;
 
    function IsTeen(): Boolean
    {
        return age >= MIN_TEEN_AGE && age <= MAX_TEEN_AGE;
    }
}

Here’s how it’d work in C#:

class Person
{
    private const int MinTeenAge = 13;
    private const int MaxTeenAge = 19;
    int Age;
 
    bool IsTeen()
    {
        return Age >= MinTeenAge && Age <= MaxTeenAge;
    }
}

One important difference is that in C# you can only make basic types (e.g. int) and strings const. This is because the field will not actually exist. Instead, it’s erased and inlined everywhere that it’s used. This means that it’s inherently a static variable, so you don’t need to declare it as static. The Person class in C# will actually be compiled like this:

class Person
{
    int Age;
 
    bool IsTeen()
    {
        return Age >= 13 && Age <= 19;
    }
}

In AS3, the const keyword is just for compile-time checking and won’t result in any inlining. If you want that behavior in C# or need to use non-basic types (e.g. Person), you need to use the readonly keyword instead:

class Person
{
    static readonly Person Newborn = new Person(0);
    readonly int Age;
 
    Person(int age)
    {
        Age = age;
    }
}

Here we see two readonly fields. The Newborn field is declared static since readonly fields are not necessarily so. It’s initialized where it’s declared just like you must do with const fields in AS3. However, the Age field is readonly but not static. It’s initialized in the construct, where it must be initialized in C#.

Lastly, here’s a comparison between C# and AS3 covering everything in this article:

////////
// C# //
////////
 
// Collection of classes being used by this file
using org.apache.coolstuff;
 
// Collection of classes
namespace com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private String _name;
        String Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
 
        // Simple getters and setters
        int Age { get; set; }
 
        // Read-only field
        readonly int ID;
 
        // Inlined field
        const int AdultAge = 18;
 
        // Function that can't be overridden
        sealed void Print()
        {
            Debug.Log("Name: " + name + ", ID: " + ID);
        }
    }
}
/////////
// AS3 //
/////////
 
// Collection of classes being used by this file
import org.apache.coolstuff;
 
// Collection of classes
package com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private var _name:String;
        function get name(): String
        {
            return _name;
        }
        function set name(value:String): void
        {
            _name = value;
        }
 
 
 
 
        // Simple getters and setters
        // {not supported. use complex instead.}
 
        // Read-only field
        const var ID:int;
 
        // Inlined field
        // {not supported. use compile-time constants via command-line instead.}
 
        // Function that can't be overridden
        final function print(): void
        {
            trace("Name: " + name + ", ID: " + ID);
        }
    }
}

Next time we’ll start to cover concepts that simply aren’t available in AS3. Stay tuned!

Continue to Part 4

Spot a bug? Have a question or suggestion? Post a comment!