Created
October 2, 2021 19:11
-
-
Save MichalBrylka/824050bff67a09ba91dbb6baa824da3a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using NUnit.Framework; | |
namespace DynamicCoerce | |
{ | |
public class CoercingComparer : IEqualityComparer | |
{ | |
private CoercingComparer() { } | |
public static IEqualityComparer Instance { get; } = new CoercingComparer(); | |
public new bool Equals(object x, object y) => IsEqual(x, y); | |
public int GetHashCode(object obj) => obj?.GetHashCode() ?? 000; | |
public static bool IsEqual(object left, object right) | |
{ | |
static string Coerce(object o) => !(o is string) && o is IEnumerable ie ? CoerceToString(ie) : o?.ToString() ?? "∅"; | |
string leftText = Coerce(left), rightText = Coerce(right); | |
return string.Equals(leftText, rightText, StringComparison.Ordinal); | |
} | |
private static string CoerceToString(IEnumerable list) | |
=> "[" + string.Join(", ", list.Cast<object>().Select(e => FormatValue(e, CultureInfo.InvariantCulture))) + "]"; | |
private static string FormatValue(object value, IFormatProvider formatProvider) => | |
value switch | |
{ | |
null => "∅", | |
bool b => b ? "true" : "false", | |
string s => s, | |
char c => $"\'{c}\'", | |
DateTime dt => dt.ToString("o", formatProvider), | |
IFormattable @if => @if.ToString(null, formatProvider), | |
IEnumerable ie => "[" + string.Join(", ", ie.Cast<object>().Select(e => FormatValue(e, formatProvider))) + "]", | |
_ => value.ToString() | |
}; | |
} | |
[TestFixture] | |
class Program | |
{ | |
[Test] | |
public void Test() | |
{ | |
dynamic enums = new List<Status> { Status.Done, Status.Failed, Status.New }; | |
dynamic strings = new List<string> { "Done", "Failed", "New" }; | |
//dynamic objects1 = new List<Status> { Status.Done, Status.Failed, Status.New }; | |
//dynamic objects2 = new List<object> { "Done", "Failed", "New" }; | |
//bool isEqual1 = CoercingComparer.IsEqual(enums, strings); | |
//bool isEqual2 = CoercingComparer.IsEqual(objects1, objects2); | |
//bool isEqual3 = CoercingComparer.IsEqual(objects1, enums); | |
Assert.That(enums, Is.EqualTo(strings).Using(CoercingComparer.Instance)); | |
} | |
} | |
enum Status | |
{ | |
New, | |
Done, | |
Failed | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment