Members

What a type holds - fields and their modifiers (static, readonly, const, fixed), constructors in all their forms, destructors, properties, indexers and methods, with virtual, override and final.

Last updated 10 min read Edit on GitHub

On this page

The members of a class, value, record or interface are declared inside its braces, usually grouped under access sections:

Member Form
Field T name;, T name = value;, T a, b = 2;
Constant const T Name = value;
Constructor new(parameters) { … }, and the forms below
Static constructor static new() { … }
Destructor destroy() { … }
Property T Name { get …; set …; }
Method Name(parameters) : Result { … } or => expression;
Operator op +(T a, T b) : T … (see Operators)
Nested type any type declaration (see Declarations)
Reactive member reactive, computed, reacts (see Reactive code)

Fields

A field is declared like a variable. It can have an initializer, which runs when the object is made, before the constructor's body. Several fields of one type can share a declaration:

Antril
public class Point
{
	public:
		i32 X = 1, Y = 2, Z;
		readonly str Name = "p";
}

A field without an initializer starts at zero when its type has one (numbers, bool, enums, values, nullable types). A field of a class type or str with no initializer must be set by every constructor before it is used.

Modifier On a field
static One field for the type, not one per object: Type.Name. A static field of a generic type starts with a constant (AN1022).
readonly Only the type's constructors assign it (AN2070 elsewhere). Every field of a record is readonly.
const A constant: see below.
fixed An inline array kept inside the object or value: fixed u8[16] Name;, or in a final class, fixed T[] items;. See Memory.
reactive A field that is a signal. See Reactive code.

A field cannot be void (AN1021), and a name can be declared once per type (AN1020). virtual, override and final do not apply to fields (AN1102).

Constants

const T Name = value; declares a constant: a value computed when the program compiles and written into the code where it is used. A constant is static by nature; static, readonly, fixed and reactive do not go with it (AN1086). Constants can be declared in a type, in a namespace and inside a body.

AntrilRun
import System;

public value Point
{
	public:
		i32 X;
		i32 Y;
		new(i32 X, i32 Y);
}

public static class Limits
{
	public:
		const i32 Base = 10;
		const i64 Widest = Int32.MaxValue + 1i64;
		const str Label = "max " + "size";
		const f64 Half = Base / 2.0;
		const Point Origin = new Point(Base, -Base);
}

Main()
{
	const i32 local = Limits.Base * 3;
	Console.WriteLine(Limits.Widest + " " + Limits.Label + " " + Limits.Half);
	Console.WriteLine(Limits.Origin.Y + local);
}
Terminal
larva run
2147483648 max size 5
20
  • The type of a constant is a number, bool, a character, str, an enum, a nullable type (for null) or a value (AN1088). Arrays and classes are not constants.
  • Its value is made of literals, other constants (wherever they are declared, even later in the file), enum members, the operators - ~ ! + - * / % & | ^ << >> && || ?? == != < <= > >=, casts between numbers and enums, and ?: (AN1091 otherwise). Integer arithmetic wraps as it does at run time.
  • A value constant is made with new and constant arguments (AN1089), and none of its fields can change.
  • A constant cannot depend on itself (AN1090) and cannot be assigned (AN2071, AN2140).
  • The limits of the number types (Int32.MaxValue, Float64.Epsilon…) are constants. Name them through the library type: i32.MaxValue gives the same value, but not as a constant (AN1091 in a constant).

Constructors

new(parameters) { … } is a constructor. A type can have several, with different parameters (two with the same ones are AN1033). A class without any gets an empty one. Only classes and values have constructors (AN1032).

Form What it does
new(i32 x) { … } A constructor with a body.
new(i32 X, i32 Y); No body: each parameter is stored in the field of the same name. A parameter that names no field is AN2131.
new(i32 id, f64 Radius) : base(id); No body, and the parameters that name no field go to the base constructor.
new(i32 id) : base(id) { … } Calls a base class constructor first, then runs the body.
new(f64 r) : (0, r); Calls another constructor of the same type (with or without a body after it).
new(i32 n) : fixed(n) { … } Says how many elements the object's fixed T[] field holds. It is the whole header: no : base with it (AN1098).
private: new() { } A constructor only the type itself can call.
static new() { … } The static constructor: runs once, before the type is first used. No parameters (AN1048), one per type (AN1049), none in generic types (AN1050).
AntrilRun
import System;

public class Shape
{
	public:
		i32 Id;
		new(i32 Id);
}

public class Circle : Shape
{
	public:
		f64 Radius;
		new(i32 id, f64 Radius) : base(id);
		new(f64 r) : (0, r);
		new() : (1.0) { Console.WriteLine("default circle"); }
}

Main()
{
	Circle c = new Circle(7, 2.5);
	Circle d = new Circle();
	Console.WriteLine(c.Id + " " + c.Radius + " " + d.Id + " " + d.Radius);
}
Terminal
larva run
default circle
7 2.5 0 1

The access of a constructor controls who can make objects: new Token() from outside a type whose constructors are private is AN1401.

Destructors

A class can declare one destructor, destroy(): no parameters, no result, not static (AN1078). It runs once, when the object stops existing, and a derived class's destructor runs before its base's. When that is depends on the project's memory mode; see Memory. Values, interfaces and enums have none (AN1077).

Antril
public class File
{
	public:
		destroy() { Console.WriteLine("closed"); }
}

Properties

A property is read and written like a field, through accessors:

Form What it is
i32 Count { get; set; } Stored in a hidden field.
i32 Count { get; private set; } The same, with a setter only the type can use.
i32 Area { get => w * h; } Computed each time it is read.
f64 C { get => c; set { c = value; Changed(); } } Bodies for each accessor; in set, the new value is value.
static i32 Opened { get; set; } A property of the type.
str Name { base get; } In an interface: an accessor each implementing type writes.
AntrilRun
import System;

public class Temperature
{
	f64 celsius;

	public:
		f64 Celsius { get => celsius; set { celsius = value; Changes += 1; } }
		f64 Fahrenheit { get => celsius * 9 / 5 + 32; }
		static i32 Changes { get; set; }
		virtual str Unit { get => "C"; }
}

public class Kelvin : Temperature
{
	public:
		override str Unit { get => "K"; }
}

Main()
{
	Temperature t = new Kelvin();
	t.Celsius = 100;
	Console.WriteLine(t.Fahrenheit + " " + Temperature.Changes + " " + t.Unit);
}
Terminal
larva run
212 1 K
  • A property needs a get (AN1044). Assigning one without set is AN2095.
  • An accessor can have a narrower access than its property (private set).
  • Properties can be static, virtual and override, like methods.
  • Properties belong to classes, values and interfaces (AN1043).

Warning

Not yet available:

  • Setting a get-only property such as str Name { get; } in a constructor (AN2095). Use { get; private set; }.
  • An initializer on a property: i32 Count { get; } = 4;.

Indexers

Antril has no indexer declaration. Indexing an object calls its methods by name:

Written Calls
x[i], x[i, j] x.At(i), x.At(i, j)
x[i] = v x.SetAt(i, v)
AntrilRun
import System;

public class Board
{
	i32[] cells = new i32[9];

	public:
		At(i32 x, i32 y) : i32 => cells[y * 3 + x];
		SetAt(i32 x, i32 y, i32 v) { cells[y * 3 + x] = v; }
}

Main()
{
	Board b = new Board();
	b[1, 2] = 7;
	Console.WriteLine(b[1, 2]);
}
Terminal
larva run
7

List<T>, Dictionary<K, V> and str are indexed this way.

Warning

Not yet available: compound assignment through an indexer, b[1, 2] += 1 (AN2096). Write b[1, 2] = b[1, 2] + 1.

Methods

A method is a function declared in a type: Name(parameters) : Result with a block body, an expression body after =>, or (in a base class or interface) no body. Without : Result it returns nothing. Methods follow the rules of functions: overloads, generic methods, async, iterators.

  • An instance method runs on an object: inside it, this is that object (or that value), and the type's members can be named directly.
  • A static method belongs to the type and is called through it: MathX.Twice(4). It has no this (AN2029), and instance members are not available in it (AN2034).
  • A method and a field or property cannot share a name (AN1031).

virtual, override and final

Word Meaning
virtual Derived classes may replace this method or property.
override Replaces a virtual one of a base class, with the same parameters and result (AN1036 if there is none, AN1037 if the result differs).
final override Replaces it, and stops further overrides (AN1039).
  • Methods are not virtual unless they say so. A method that has the same signature as a virtual method of its base must say override (AN1038).
  • Only instance methods of classes are virtual (AN1029); virtual in a class nothing can derive from is AN1100.
  • final alone, or with virtual, is AN1101: a method that is not virtual is final already.
  • A bodiless method in a base class is abstract: derived classes must override it.
  • Overloads of a virtual method are separate: overriding one does not replace the others.
Antril
public class A
{
	public:
		virtual Name() : str => "a";
}

public class B : A
{
	public:
		final override Name() : str => "b";
}

Modifiers on members

Word Members Meaning
public, private, internal, inherited, friendly, file all Access. See Access.
static fields, properties, methods, constructors Belongs to the type.
readonly fields Assigned only by constructors.
const fields A compile-time constant.
fixed fields An inline array.
virtual, override, final methods, properties Overriding.
unsafe methods, constructors May use pointers.
async methods Returns a task; see Iterators and async.
reactive, computed, reacts fields, properties, methods See Reactive code.

A modifier can be written once per declaration (AN0013), and one access word at most (AN0038).

Was this page helpful?

No address is stored; your user name is, if you are signed in.

Esc