# constructor

> A class declares one constructor — its name is the class name, it takes no return type, and it runs when you write new T(args). The constructor body runs first; object initializers { Member = value } apply after it; new T(args) evaluates to the constructed object.

<!-- id: class-constructors · area: class · stability: stable · html: https://osysharp.com/reference/class/constructors/ -->

## Summary        {#summary}
A **constructor** initializes a `class` instance. It is declared as a member whose name is the class name and
which has **no return type**; you invoke it with `new T(args)`. The constructor **body runs first**, then any
object initializers `{ Member = value }` are applied **on top** (so an initializer wins over a value the body
set). `new T(args)` evaluates to the constructed object.

## Signature      {#signature}
```osy syntax
class T {
  public T(<Type> p1, <Type> p2 = <default>) {   // no return type
    <statements>                                  // may read the params and assign this fields
  }

  public T() : this(<a>, <b>) { … }              // another one, chaining to the first
}

new T(a, b)                 // run the constructor these arguments select
new T(a, b) { Note = "x" }  // …then apply the initializer
```

## Description    {#description}
- **A class may declare several constructors**, told apart by their parameter TYPES exactly as
  [methods](https://osysharp.com/reference/class/overloads/) are — `new T(args)` picks the one its arguments fit. Two that differ only in
  parameter NAMES are the same constructor declared twice, and a compile error. The name is the class name and
  there is **no return type** (a `return;` with a value is a compile error).
- **`: this(…)` chains to another constructor of the same class**, which runs FIRST — so shared setup lives in one
  place. The chained-to constructor is the one that runs `: base(…)`; a chaining constructor does not also run the
  base's, so a base constructor runs exactly once. A chain that comes back round to where it started is a compile
  error rather than unbounded recursion at construction time.
- **Visibility** follows the class-member rule: `public` makes it callable from anywhere; a bare (unmarked)
  constructor is **private** — callable only from within its own class (the factory-method pattern).
- **`new T(args)`** binds the arguments to the constructor's parameters (positional or `name: value`, with C#
  default-parameter values for omitted optionals), runs the body with the fresh instance in scope, and
  produces that instance.
- **Initializers run after the body**: `new T(args) { Member = value }` runs the constructor first, then
  assigns each initializer — so an initializer overrides whatever the constructor set for that member (C#
  order). Initializer values cannot reference the object being constructed.
- **A class with no declared constructor** uses the implicit default: `new T()` and `new T { … }` build the
  instance with no user code. Passing arguments to such a class is a compile error.
- **A field initializer runs before every constructor body** (`decimal Rate = 0.25m;`), so the body reads the
  declared value and may overwrite it — C#'s order. Object initializers are the ones that run after.
- **A required parameter must be supplied**: if the constructor has a non-optional parameter, `new T { … }`
  (no arguments) is a compile error — pass the argument.
- Durable: a suspension **inside** a constructor body survives serialize/restore, and `new T(args)` still
  evaluates to the same constructed instance on resume.

## Examples       {#examples}
```osy title="a class with a constructor" test app=constructors
class Order {
  public int Qty;
  public decimal Total;
  public string Note;
  // The ctor assigns every required member, so `new Order(5, 2m)` compiles without also naming them in an
  // initializer — the compiler infers that the constructor satisfies them (no annotation needed).
  public Order(int qty, decimal price) {
    Qty = qty;
    Total = qty * price;
    Note = "new order";
  }
}

// The constructor sets the fields from its arguments.
decimal OrderTotal() {
  var o = new Order(5, 2m);
  return o.Total;                 // 10  (5 * 2, set in the body)
}

// An initializer is applied AFTER the body — so it wins.
string OrderNote() {
  var o = new Order(5, 2m) { Note = "rush" };
  return o.Note;                  // "rush"  (the body set "new order"; the initializer overrode it)
}
```

```osy title="default parameters and the implicit default constructor" test app=constructors
class Box {
  public int Size;
  public Box(int size = 3) { Size = size; }
}

int DefaultSize() { var b = new Box(); return b.Size; }   // 3  (the constructor's default)
int GivenSize()   { var b = new Box(7); return b.Size; }  // 7

// A class with no declared constructor keeps the plain build.
class Point { public int X; public int Y; }
int Origin() { var p = new Point { X = 0, Y = 0 }; return p.X + p.Y; }   // 0
```

### Several constructors, and chaining between them   {#overloads}
Declare as many as differ in their parameter types. `: this(…)` runs another of them first, which is how shared
setup stays in one place:

```osy title="three ways to make a Panel" test app=constructors
class Panel {
  public decimal Width;
  public decimal Height;

  public Panel(decimal width, decimal height) {   // the one that actually assigns
    Width = width;
    Height = height;
  }

  public Panel(decimal width) : this(width, 20m) { }   // chains to it
  public Panel() : this(10m) { }                       // …and so does this, one hop further
}
```

Each `new` picks by its arguments, and a chain runs all the way down before the chaining body:

```osy title="each new selects, and the chain completes" run app=constructors
[Test]
void Constructors_Select_And_Chain() {
  Assert.Equal(3m, new Panel(3m, 4m).Width);
  Assert.Equal(20m, new Panel(3m).Height);     // the default the one-arg constructor passed on
  Assert.Equal(10m, new Panel().Width);        // two hops: () → (decimal) → (decimal, decimal)
}
```

## See also       {#see-also}
- [class methods](https://osysharp.com/reference/class/methods/) — instance methods on a class (the same member-body mechanism the constructor reuses)
- [Typed locals](https://osysharp.com/reference/function/typed-locals/) — declaring the local that holds a constructed instance
