Patch<T>#
A three-state field of an update record. A patch is Missing (keep the current value), Null (clear it) or carries a value (set it). Every editable field of TaskUpdate, LinkUpdate, ResourceUpdate and AssignmentUpdate is a Patch<T>, and a new update record starts with every patch Missing.
Build one with Patch<T>.Missing, Patch<T>.Null or Patch<T>.Of(value), or assign a T and the implicit conversion wraps it.
Declaration#
public readonly struct Patch<T> : IEquatable<Patch<T>>
Patch<T> is an immutable value type. default(Patch<T>) is Missing.
Properties#
| Property | Type | Description |
|---|---|---|
Kind |
PatchKind |
Which of the three states this patch is in. |
IsMissing |
bool |
true when Kind is Missing. |
IsNull |
bool |
true when Kind is Null. |
HasValue |
bool |
true when Kind is Value. |
Value |
T |
The carried value. Throws InvalidOperationException when the patch is Missing or Null. |
Methods#
TryGetValue#
public bool TryGetValue(out T value)
Returns true and the carried value when the patch has one. Returns false for Missing and Null; value is then default(T).
Equals#
public bool Equals(Patch<T> other)
public override bool Equals(object? obj)
Two patches are equal when they're in the same state and, for Value, their values are equal by EqualityComparer<T>.Default. Missing equals Missing, and Null equals Null.
GetHashCode() follows the same rule.
ToString#
public override string ToString()
Returns "Missing", "Null" or "Value(...)" with the carried value, e.g. "Value(3)".
Static members#
Missing#
public static Patch<T> Missing { get; }
A patch that leaves the field unchanged. Same as default(Patch<T>).
Null#
public static Patch<T> Null { get; }
A patch that clears the field. What clearing means depends on the field: an optional field is cleared, a field with a default goes back to that default, and a required field rejects the operation. Each update record's page lists its fields.
Of#
public static Patch<T> Of(T value)
A patch that sets the field to value.
Operators#
public static implicit operator Patch<T>(T value)
public static bool operator ==(Patch<T> a, Patch<T> b)
public static bool operator !=(Patch<T> a, Patch<T> b)
The implicit conversion calls Of(value), so update.Duration = 3 sets the field. == and != compare like Equals.
The conversion also accepts a null reference for a reference type T: Patch<Id> p = null! produces Of(null) with Kind Value, not Null. To clear a field, assign Patch<T>.Null.
PatchKind#
The state of a Patch<T>, returned by Kind.
public enum PatchKind
{
Missing,
Null,
Value,
}
| Value | Description |
|---|---|
Missing |
The field is absent; the current value stays. The default. |
Null |
The field is an explicit null; the current value is cleared. |
Value |
The field carries a new value. |
Example#
using Plen;
var update = new TaskUpdate("design")
{
Duration = 3, // Patch<double>.Of(3)
ConstraintDate = Patch<Moment>.Null, // clear the constraint date
}; // every other field stays Missing
Console.WriteLine(update.Duration); // Value(3)
Console.WriteLine(update.Progress.Kind); // Missing
if (update.Duration.TryGetValue(out var duration))
Console.WriteLine(duration); // 3
Console.WriteLine(update.ConstraintDate == Patch<Moment>.Null); // True
Related#
TaskUpdate- the update record with the most patch fieldsSchedulingChanges- the change set that carries update records- Records, ids and dates - patch fields alongside the other input types
- Editing a project - updating records in a live project