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


# IDeepCloneable<T>

A record that can be deep-copied. Input records, options classes, change sets and result classes in the package implement it, each with `T` set to its own type. You never create an `IDeepCloneable<T>` directly: call `DeepClone()` on a record such as [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>), [`TaskData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/task-data.md>) or [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>).

## Declaration

```csharp
namespace Plen;

public interface IDeepCloneable<out T>
{
    T DeepClone();
}
```

`T` is covariant (`out`).

## Methods

### DeepClone

```csharp
T DeepClone()
```

Returns a deep copy of the record. The copy shares no mutable list or nested record with the original, so either one can be changed without affecting the other.

**Returns** - a new instance of `T`.

Immutable values aren't copied: [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) instances and [`Moment`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/moment.md>) values are shared, and that's safe because neither can change. A type can document a field it shares on purpose. For example, [`LevelingResult.DeepClone`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/leveling-result.md>) keeps the same `Schedule` object.

## Generic constraint

[`Changes<TAdd, TUpdate>`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/changes.md>) requires both type arguments to implement `IDeepCloneable<T>`, so its own `DeepClone()` can copy every record in `Add` and `Update`:

```csharp
public sealed class Changes<TAdd, TUpdate> : IDeepCloneable<Changes<TAdd, TUpdate>>
    where TAdd : IDeepCloneable<TAdd>
    where TUpdate : IDeepCloneable<TUpdate>
```

## Example

Change a copy of a result and leave the original as it was:

```csharp
using Plen;

var data = new ProjectData
{
    Tasks = [new TaskData(1) { Duration = 2.0 }],
};

var result = Engine.Schedule(data, new SolveOptions());

ScheduleResult copy = result.DeepClone();
copy.Updates.Clear();

Console.WriteLine(result.Updates.Count); // unchanged
```

## Related

- [`Changes<TAdd, TUpdate>`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/changes.md>) - requires its records to be cloneable
- [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) - a cloneable input record
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) - a cloneable result
- [Records, ids and dates](<https://docs.dhtmlx.com/planning-engine/net/records-ids-and-dates.md>) - how the record types work
