Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Class

`static` methods

static <Return> <Name>(<params>) { … } public static <Return> <Name>(<params>) { … }

A `static` method belongs to the type rather than to any instance, and is called on the type name — `Money.Round(x)`. It has no `this`, so it cannot read the class's instance fields; it can call the class's other static methods and read its `const` values by bare name. Fields cannot be static: a `const` covers the fixed values, and anything that would need to change belongs to an instance or to an entity.

stable6 examples compiled by CIclassmethodsstatic

Summary#

A static method is called on the type, not on a value:

class Money {
  public decimal Amount;

  public static decimal Round(decimal value) {
    return Math.Round(value, 2);
  }
}

decimal RoundAPrice() {
  return Money.Round(19.999m);       // on the TYPE — there is no Money instance here
}

Reach for it when the operation is about the type but not about any particular value of it — a conversion, a validation, a calculation over its arguments.

Signature#

static <Return> <Name>(<params>) { … }
public static <Return> <Name>(<params>) { … }

static goes after the visibility word, as in C#. It applies to methods only.

Description#

A static method has no this#

That is the whole of the rule, and everything else follows from it. There is no instance, so there is nothing for an instance field to be read from:

class Money {
  public decimal Amount;

  public static decimal Doubled() {
    return Amount * 2m;              // ✗ 'Amount' belongs to an INSTANCE
  }

  public static decimal Half() {
    return this.Amount / 2m;         // ✗ `this` has no meaning in a static method
  }
}

Take the value as a parameter instead — which is usually what the method wanted anyway:

class Tax {
  public static decimal Net(decimal gross, decimal rate) {
    return gross / (1m + rate);
  }
}

What a static method CAN see of its own class#

Its other static methods and its const values, both by bare name — the same rule as C#:

class Rate {
  public const decimal Standard = 0.25m;

  public static decimal Apply(decimal amount) {
    return amount * (1m + Standard);      // a const, by bare name
  }

  public static decimal ApplyTwice(decimal amount) {
    return Apply(Apply(amount));          // another static, by bare name
  }
}

[Test]
void Statics_Reach_Statics_And_Consts() {
  Assert.Equal(125m, Rate.Apply(100m));
  Assert.Equal(156.25m, Rate.ApplyTwice(100m));
}

An instance method may call its class's static methods the same way — it simply does not pass its this along:

class Line {
  public decimal Gross;

  public decimal Net() {
    return Tax.Net(Gross, 0.25m);
  }
}

Call it on the type, never through a value#

The two directions are both compile errors, and each says which spelling to use:

var m = new Money { Amount = 1m };

m.Round(2.5m);          // ✗ 'Money.Round' is static — call it as `Money.Round(…)`
Money.Amount;           // ✗ 'Money.Amount' is an instance member — access it through an instance

Refusing the first is C#'s rule too, and it is worth the strictness: m.Round(…) reads as though the method can see m, and it cannot — the receiver would be evaluated and discarded.

Statics inherit#

A static method declared on a base class is callable on a derived one, like any other inherited member:

class Shape {
  public string Name;
  public static decimal Zero() { return 0m; }
}

class Circle : Shape {
  public decimal Radius;
}

decimal ZeroThroughTheSubclass() {
  return Circle.Zero();          // Shape declares it; Circle inherits it
}

It cannot be virtual, override or abstract, and combining them is a compile error. Those words choose a body from the receiver's runtime type, and a static call has no receiver to choose by.

Static methods overload#

Exactly like instance methods — a name maps to a set, and the call site picks by the arguments. See Method overloads for the rule.

class Fmt {
  public static string Of(decimal d) { return d.ToString(); }
  public static string Of(decimal d, string unit) { return d.ToString() + " " + unit; }
}

Fields cannot be static#

static applies to methods only. A static field would be mutable state shared by every application running in the host process, with no per-app copy to reset — so it is refused, in as many words:

class Counter {
  public static decimal Total;         // ✗ cannot be `static`
}

There are three things people reach for it for, and each has its own answer:

what you wantreach for
a fixed value the whole program sharesconst — already static, and needs no modifier
a value that belongs to one objectan ordinary field
state that outlives a requestan entity — stored, per-app, and secured

For the same reason there is no static constructor: it would exist to initialize static state, and there is none.

See also#

Related

class methods

Behaviour attached to a class — a method with a receiver, called as value.Method(). Classes are in-memory values, so a…

Classes

A class is an in-memory shape — data plus the behaviour that belongs to it — and it never touches the database. That is…

Method overloads

A class can declare several methods with the same name, as long as they differ in their parameter types. Each call…

constructor

A class declares one constructor — its name is the class name, it takes no return type, and it runs when you write new…

type visibility (public / internal)

A top-level type carries a public or internal visibility that decides whether code outside its namespace can name it…