public override string ToString()
        {
            var stringBuilder = new StringBuilder(RootNoteName.ToString());

            var quality = Quality;

            if (quality != null)
            {
                var qualityValue = quality.Value;
                stringBuilder.Append(qualityValue != ChordQuality.Major ? QualitiesSymbols[qualityValue] : string.Empty);
            }

            var extensionInterval = ExtensionInterval;

            if (extensionInterval != null)
            {
                var extensionQuality    = extensionInterval.Quality;
                var extensionNumber     = extensionInterval.Number;
                var extensionAlteration = ExtensionAlteration;

                if (extensionAlteration == null)
                {
                    var printQuality = (extensionNumber != 7 && extensionQuality != IntervalQuality.Major) ||
                                       (extensionNumber == 7 && extensionQuality != IntervalQuality.Minor);
                    stringBuilder.Append($"{(printQuality ? IntervalQualitiesSymbols[extensionQuality] : string.Empty)}{extensionNumber}");
                }
                else
                {
                    stringBuilder.Append($"7{(extensionAlteration == Accidental.Sharp ? Note.SharpShortString : Note.FlatShortString)}{extensionNumber}");
                }
            }

            var suspensionIntervalNumber = SuspensionIntervalNumber;

            if (suspensionIntervalNumber != null)
            {
                stringBuilder.Append($"sus{suspensionIntervalNumber}");
            }

            stringBuilder.Append(string.Join(string.Empty, AddedToneIntervals.Where(i => !AlteredIntervals.Any(t => t.IntervalNumber == i.Number)).Select(i => $"add{i.Number}")));

            stringBuilder.Append(string.Join(string.Empty, AlteredIntervals));

            var bassNoteName = BassNoteName;

            if (bassNoteName != null)
            {
                stringBuilder.Append($"/{bassNoteName.Value.ToString().Replace(Note.SharpLongString, Note.SharpShortString)}");
            }

            return(stringBuilder.ToString());
        }
 public override int GetHashCode()
 {
     unchecked
     {
         var result = 17;
         result = result * 23 + RootNoteName.GetHashCode();
         result = result * 23 + (Quality?.GetHashCode() ?? 0);
         result = result * 23 + (BassNoteName?.GetHashCode() ?? 0);
         result = result * 23 + (ExtensionInterval?.GetHashCode() ?? 0);
         result = result * 23 + (AddedToneIntervals.FirstOrDefault()?.GetHashCode() ?? 0);
         result = result * 23 + (AlteredIntervals.FirstOrDefault()?.GetHashCode() ?? 0);
         result = result * 23 + (SuspensionIntervalNumber?.GetHashCode() ?? 0);
         result = result * 23 + SeventhQuality.GetHashCode();
         return(result);
     }
 }