Skip to content

Instantly share code, notes, and snippets.

@MichalBrylka
Created October 2, 2021 19:11
Show Gist options
  • Save MichalBrylka/824050bff67a09ba91dbb6baa824da3a to your computer and use it in GitHub Desktop.
Save MichalBrylka/824050bff67a09ba91dbb6baa824da3a to your computer and use it in GitHub Desktop.
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