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


# Skill

One skill a [`Worker`](<https://docs.dhtmlx.com/planning-engine/net/api/assign/worker.md>) has, with its value. Use `0`/`1` for skills a worker either has or doesn't, and an integer grade for skills with levels. Create skills with an object initializer and put them in [`Worker.Skills`](<https://docs.dhtmlx.com/planning-engine/net/api/assign/worker.md>).

A [`SkillMatch`](<https://docs.dhtmlx.com/planning-engine/net/api/assign/requirement.md#skillmatch>) compares this value when [`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>) picks candidates. A skill the worker doesn't list counts as `0` there.

## Declaration

```csharp
namespace Plen.Assign;

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

`Id` is `required`, so set it in the object initializer.

## Properties

| Property | Type | Default | Description |
|---|---|---|---|
| `Id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | required | Skill id. Must be unique within one worker's `Skills`. |
| `Value` | `double` | `1.0` | Skill value: `0`/`1` for a yes/no skill, an integer grade otherwise. Must be finite. |

[`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>) rejects a duplicate `Id` or a non-finite `Value` with an [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) at `pool.workers[i].skills[j].id` or `.value`. See [Errors](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md#errors>).

## Methods

### DeepClone

```csharp
public Skill DeepClone()
```

Returns a copy with the same `Id` and `Value`.

### Equals

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

Two skills are equal when their `Id`s are equal and their `Value`s are equal by `==`. `GetHashCode()` follows the same rule.

### ToString

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

Returns a readable rendering of `Id` and `Value`, for logging.

## Example

```csharp
using Plen.Assign;

var bob = new Worker
{
    Resource = "bob",
    Skills =
    [
        new Skill { Id = "backend" },          // has the skill (Value = 1.0)
        new Skill { Id = "qa", Value = 2 },    // QA grade 2
    ],
};
```

## Related

- [`Worker`](<https://docs.dhtmlx.com/planning-engine/net/api/assign/worker.md>) - the worker that lists the skill
- [`SkillMatch`](<https://docs.dhtmlx.com/planning-engine/net/api/assign/requirement.md#skillmatch>) - the condition that compares skill values
- [`SkillLayer.Slots`](<https://docs.dhtmlx.com/planning-engine/net/api/skill-layer-slots.md>) - the call that validates and reads skills
- [Skills and requirements](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/skills-and-requirements.md>) - describing who can do what
