diff --git a/SabreTools.DatItems/DatItem.cs b/SabreTools.DatItems/DatItem.cs
index 675814db..eb9d1d88 100644
--- a/SabreTools.DatItems/DatItem.cs
+++ b/SabreTools.DatItems/DatItem.cs
@@ -16,9 +16,6 @@ namespace SabreTools.DatItems
///
/// Base class for all items included in a set
///
- ///
- /// TODO: Can this be made into a `record` type for easier comparison?
- ///
[JsonObject("datitem"), XmlRoot("datitem")]
[XmlInclude(typeof(Adjuster))]
[XmlInclude(typeof(Analog))]
@@ -700,4 +697,55 @@ namespace SabreTools.DatItems
#endregion // Static Methods
}
+
+ ///
+ /// Base class for all items included in a set that are backed by an internal model
+ ///
+ public abstract class DatItem : DatItem, IEquatable>, IComparable>, ICloneable where T : Models.Metadata.DatItem
+ {
+ #region Cloning Methods
+
+ ///
+ /// Clone the DatItem
+ ///
+ /// Clone of the DatItem
+ public override abstract object Clone();
+
+ #endregion
+
+ #region Comparision Methods
+
+ ///
+ public int CompareTo(DatItem? other)
+ {
+ try
+ {
+ if (GetName() == other?.GetName())
+ return Equals(other) ? 0 : 1;
+
+ return string.Compare(GetName(), other?.GetName());
+ }
+ catch
+ {
+ return 1;
+ }
+ }
+
+ ///
+ /// Determine if an item is a duplicate using partial matching logic
+ ///
+ /// DatItem to use as a baseline
+ /// True if the items are duplicates, false otherwise
+ public virtual bool Equals(DatItem? other)
+ {
+ // If we don't have a matched type, return false
+ if (GetFieldValue(Models.Metadata.DatItem.TypeKey) != other?.GetFieldValue(Models.Metadata.DatItem.TypeKey))
+ return false;
+
+ // Compare the internal models
+ return _internal.EqualTo(other._internal);
+ }
+
+ #endregion
+ }
}