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


# Roster

A snapshot of the project's accepted state: the scheduled leaf tasks, the resources and the active assignments, as ids. [`Project.Roster`](<https://docs.dhtmlx.com/planning-engine/net/api/project-roster.md>) returns it. Use it to build your own [`Slot`](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/slot.md>) lists for [`SuggestAssignments`](<https://docs.dhtmlx.com/planning-engine/net/api/project-suggest-assignments.md>). [`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>) reads it internally.

## Declaration

```csharp
namespace Plen;

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

A `Roster` is a new object on every call and isn't connected to the project. Changing its lists doesn't affect the project.

## Properties

| Property | Type | Description |
|---|---|---|
| `Tasks` | `List<`[`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>)`>` | Scheduled leaf tasks, in model order. Summary tasks and unscheduled tasks are left out. |
| `Resources` | `List<`[`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>)`>` | Resources, in model order. |
| `Assignments` | `List<`[`RosterAssignment`](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/roster.md#rosterassignment>)`>` | Active assignments, in model order. |

Every list defaults to empty.

## Methods

### DeepClone

```csharp
public Roster DeepClone()
```

Returns a copy that shares no list or nested `RosterAssignment` with the original.

### Equals

```csharp
public bool Equals(Roster? other)
```

Value equality: the three lists are compared element by element, in order. `GetHashCode` follows the same rule.

### ToString

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

Returns a debug dump of the three lists.

## RosterAssignment

One active assignment in [`Roster.Assignments`](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/roster.md#properties>).

```csharp
namespace Plen;

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

| Property | Type | Description |
|---|---|---|
| `Id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | Assignment id. Required. |
| `Task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | Id of the assigned task. Required. |
| `Resource` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | Id of the assigned resource. Required. |

`DeepClone`, `Equals` and `ToString` behave as on `Roster`. Equality compares all three ids.

## Example

```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 = 2.0 }],
    Resources = [new ResourceData { Id = "ann" }, new ResourceData { Id = "bob" }],
    Assignments = [new AssignmentData { Id = "a1", Task = 1, Resource = "ann", Value = 1.0 }],
};

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

var roster = project.Roster();
Console.WriteLine($"tasks: {string.Join(", ", roster.Tasks)}");
Console.WriteLine($"resources: {string.Join(", ", roster.Resources)}");
foreach (var a in roster.Assignments)
    Console.WriteLine($"{a.Id}: task {a.Task} -> {a.Resource}");
```

## Related

- [`Project.Roster`](<https://docs.dhtmlx.com/planning-engine/net/api/project-roster.md>) - the call that returns it
- [`Slot`](<https://docs.dhtmlx.com/planning-engine/net/api/core/suggest/slot.md>) - the slots you build from it
- [`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, reading the roster internally
- [Skills and requirements](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/skills-and-requirements.md>) - slots from workers and requirements
