Skip to content

Commit

Permalink
equality improvements for ConsoleString
Browse files Browse the repository at this point in the history
  • Loading branch information
adamabmsft committed Dec 31, 2024
1 parent 8058a0d commit 59c0b03
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 64 deletions.
6 changes: 4 additions & 2 deletions PowerArgs/Extensions/Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static List<T> ToList<T>(this Array a)
return ret;
}

public static T MaxOrDefault<T>(this IEnumerable<T> src, T defaultVal = default(T)) where T : IComparable
public static T MaxOrDefault<T>(this IEnumerable<T> src, T? defaultVal = default) where T : IComparable<T>
{
var max = defaultVal;
foreach(var val in src)
Expand All @@ -41,7 +41,9 @@ public static List<T> ToList<T>(this Array a)
return max;
}

public static T MinOrDefault<T>(this IEnumerable<T> src, T defaultVal = default(T)) where T : IComparable


public static T MinOrDefault<T>(this IEnumerable<T> src, T defaultVal = default(T)) where T : IComparable<T>
{
var min = defaultVal;
foreach (var val in src)
Expand Down
103 changes: 52 additions & 51 deletions PowerArgs/HelperTypesPublic/ConsoleString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,7 @@ public override string ToString()
/// <returns></returns>
public override bool Equals(object obj)
{

if (obj is char) return Value.Equals((char)obj);
if (obj is ConsoleCharacter == false) return false;
var other = (ConsoleCharacter)obj;

return this.Value == other.Value &&
this.ForegroundColor == other.ForegroundColor &&
this.BackgroundColor == other.BackgroundColor &&
this.IsUnderlined == other.IsUnderlined;
return obj is ConsoleCharacter other && Equals(other);
}

public bool Equals(ConsoleCharacter other)
Expand Down Expand Up @@ -433,7 +425,7 @@ public bool EqualsIn(in ConsoleCharacter other)
/// <returns>the internal char's hashcode.</returns>
public override int GetHashCode()
{
return Value.GetHashCode();
return HashCode.Combine(Value, ForegroundColor, BackgroundColor, IsUnderlined);
}

/// <summary>
Expand Down Expand Up @@ -465,7 +457,7 @@ public ConsoleCharacter ToUnderlined()
/// <summary>
/// A wrapper for string that encapsulates foreground and background colors. ConsoleStrings are immutable.
/// </summary>
public class ConsoleString : IEnumerable<ConsoleCharacter>, IComparable<string>, ICanBeAConsoleString
public class ConsoleString : IEquatable<ConsoleString>, IEnumerable<ConsoleCharacter>, IComparable<string>, ICanBeAConsoleString
{
/// <summary>
/// The console provider to use when writing output
Expand Down Expand Up @@ -1491,34 +1483,37 @@ public List<List<ConsoleCharacter>> GroupByFormatting()
return ret;
}

/// <summary>
/// Compare this ConsoleString to another ConsoleString or a plain string.
/// </summary>
/// <param name="obj">The ConsoleString or plain string to compare to.</param>
/// <returns>True if equal, false otherwise</returns>
public override bool Equals(object obj)
{
if (obj is string) return ToString().Equals(obj as string);

ConsoleString other = obj as ConsoleString;
if (object.ReferenceEquals(other, null)) return false;
if (other.Length != this.Length) return false;
/// <summary>
/// Compares this ConsoleString with another ConsoleString for equality.
/// </summary>
public bool Equals(ConsoleString other)
{
if (other is null || Length != other.Length)
return false;

for (int i = 0; i < Length; i++)
{
if (!this[i].Equals(other[i]))
return false;
}

for (int i = 0; i < this.Length; i++)
{
if (this.characters[i] != other.characters[i]) return false;
}
return true;
}

return true;
}
/// <summary>
/// Avoid boxing by overriding Equals(object) with an explicit type check.
/// </summary>
public override bool Equals(object obj)
{
return obj is ConsoleString other && Equals(other);
}

/// <summary>
/// Compare this ConsoleString to another ConsoleString.
/// </summary>
/// <param name="other">The ConsoleString to compare to.</param>
/// <returns>True if equal, false otherwise</returns>
public int CompareTo(string other)
/// <summary>
/// Compare this ConsoleString to another ConsoleString.
/// </summary>
/// <param name="other">The ConsoleString to compare to.</param>
/// <returns>True if equal, false otherwise</returns>
public int CompareTo(string other)
{
return ToString().CompareTo(other);
}
Expand All @@ -1529,8 +1524,13 @@ public int CompareTo(string other)
/// <returns>the hashcode of the underlying string</returns>
public override int GetHashCode()
{
return ToString().GetHashCode();
}
var hash = new HashCode();
for (int i = 0; i < characters.Length; i++)
{
hash.Add(characters[i]);
}
return hash.ToHashCode();
}

/// <summary>
/// Operator overload that concatenates 2 ConsoleString instances and returns a new one.
Expand Down Expand Up @@ -1573,28 +1573,29 @@ public override int GetHashCode()
/// <returns>True if they are the same, false otherwise</returns>
public static bool operator ==(ConsoleString a, ConsoleString b)
{
if (object.ReferenceEquals(a, null)) return object.ReferenceEquals(b, null);
return a.Equals(b);
}
if (ReferenceEquals(a, b))
return true;

if (a is null || b is null)
return false;

return a.Equals(b);
}

/// <summary>
/// Compares 2 ConsoleStrings for inequality.
/// </summary>
/// <param name="a">The left operand</param>
/// <param name="b">The right operand</param>
/// <returns>False if they are the same, true otherwise</returns>
public static bool operator !=(ConsoleString a, ConsoleString b)
{
if (object.ReferenceEquals(a, null)) return !object.ReferenceEquals(b, null);
return a.Equals(b) == false;
}
public static bool operator !=(ConsoleString a, ConsoleString b) => !(a == b);

/// <summary>
/// Gets the character at the specified index
/// </summary>
/// <param name="index">the index of the character to find</param>
/// <returns>the character at the specified index</returns>
public ConsoleCharacter this[int index]
/// <summary>
/// Gets the character at the specified index
/// </summary>
/// <param name="index">the index of the character to find</param>
/// <returns>the character at the specified index</returns>
public ConsoleCharacter this[int index]
{
get
{
Expand Down
11 changes: 0 additions & 11 deletions PowerArgsTestCore/Core/ConsoleStringTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,6 @@ public void TestConsoleStringEdgeCases()
Assert.IsFalse(new ConsoleCharacter('a').Equals(null));
Assert.IsFalse(new ConsoleCharacter('a').Equals(0));

new ConsoleCharacter('a').GetHashCode();
new ConsoleString("Adam").GetHashCode();

Assert.IsTrue(new ConsoleString("Adam").Equals("Adam"));
Assert.IsTrue(new ConsoleCharacter('A').Equals('A'));

Assert.IsTrue(new ConsoleCharacter('A') == 'A');
Assert.IsTrue(new ConsoleCharacter('A') != 'B');
Assert.IsFalse(new ConsoleCharacter('A') == null);
Assert.IsTrue(new ConsoleCharacter('A') != null);

Assert.IsTrue(new ConsoleCharacter('A') == new ConsoleCharacter('A'));
Assert.IsTrue(new ConsoleCharacter('A') != new ConsoleCharacter('B'));

Expand Down

0 comments on commit 59c0b03

Please sign in to comment.