[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/slot/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Slot

One position to staff on one task: the task, the resources eligible for it, and the assignment that fills it, if any. Pass a list of slots to [`Project.SuggestAssignments`](<https://docs.dhtmlx.com/planning-engine/net/api/project-suggest-assignments.md>). Build them yourself with the constructor, or get them from skills and requirements with [`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>).

A slot carries no skills, only resource ids.

## Declaration

```csharp
namespace Plen;

public sealed class Slot : IDeepCloneable<Slot>, IEquatable<Slot>
```

`Id`, `Task` and `Allowed` are `required`. Set them in an object initializer or use the constructor.

## Constructors

### Slot(Id, Id, List<Id>)

```csharp
public Slot(Id id, Id task, List<Id> allowed)
```

Creates an empty slot with `Value = 1.0` and `Assignment = null`. The list is stored as passed, not copied.

| Name | Type | Description |
|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | Slot id. |
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | Task to staff. |
| `allowed` | `List<Id>` | Eligible resources, in preference order. |

## Properties

| Property | Type | Default | Description |
|---|---|---|---|
| `Id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | required | Slot id. An assignment created to fill the slot gets this id, so after you commit it, set `Assignment` to the slot id to keep the binding on the next run. |
| `Task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | required | A scheduled leaf task. |
| `Allowed` | `List<Id>` | required | Resources eligible for the slot. The order is the tie-break preference when two candidates score the same. |
| `Value` | `double` | `1.0` | Units of the assignment created when the slot is filled (`1.0` = 100 %). Must be finite and greater than 0. |
| `Assignment` | [`Id?`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | `null` | The active assignment on `Task` that fills the slot. `null` means the slot is empty. |

The slot's category (empty, or filled by a resource inside or outside `Allowed`) follows from `Assignment` and `Allowed`. It decides whether the slot is filled, repaired or rebalanced; see [`AssignTarget`](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/suggest-options.md#assigntarget>).

[`Project.SuggestAssignments`](<https://docs.dhtmlx.com/planning-engine/net/api/project-suggest-assignments.md>) checks every slot before it runs. The checks and their [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) paths are listed under [Errors](<https://docs.dhtmlx.com/planning-engine/net/api/project-suggest-assignments.md#errors>).

## Methods

### DeepClone

```csharp
public Slot DeepClone()
```

Returns a deep copy. `Allowed` is copied, so nothing is shared with the original.

### Equals

```csharp
public bool Equals(Slot? other)
public override bool Equals(object? obj)
```

Two slots are equal when `Id`, `Task`, `Value` and `Assignment` are equal and `Allowed` holds the same ids in the same order. `Value` is compared with `==`.

`GetHashCode()` follows the same rule.

### ToString

```csharp
public override string ToString()
```

Returns a readable rendering of every property, for logging.

## Example

Staff task `1` with one reviewer at half time, chosen from `ann` and `bob`, then commit the pick.

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0)
    ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks = [new TaskData(1) { StartDate = monday, Duration = 3.0 }],
    Resources = [new ResourceData { Id = "ann" }, new ResourceData { Id = "bob" }],
};

var project = new Project();
project.Solve(data, new SolveOptions());

var slots = new List<Slot>
{
    new("review", 1, ["ann", "bob"]) { Value = 0.5 },
};

var result = project.SuggestAssignments(slots, new SuggestOptions());
foreach (var step in result.Steps)
    Console.WriteLine($"{step.Slot}: {step.ToResource}");

project.Apply(result.Changes);
// On the next run, bind the slot to the assignment it created:
// new("review", 1, ["ann", "bob"]) { Value = 0.5, Assignment = "review" }
```

## Related

- [`Project.SuggestAssignments`](<https://docs.dhtmlx.com/planning-engine/net/api/project-suggest-assignments.md>) - the call that takes the slots
- [`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>) - builds slots from skills and requirements
- [`Project.Roster`](<https://docs.dhtmlx.com/planning-engine/net/api/project-roster.md>) - reads tasks, resources and assignments to build your own slots
- [Suggesting assignments](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/suggesting-assignments.md>) - how slots are filled, repaired and rebalanced
- [Skills and requirements](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/skills-and-requirements.md>) - slots from workers and requirements
