Reputation: 440
I really like the C# 9 records. However, I can't find an elegant and concise way to accomplish somethink like this:
record MyKey(string Foo, int Bar);
[Fact]
public void ShouldEqualIgnoreCase()
{
MyKey a = new("ID", 42);
MyKey b = new("Id", 42);
Assert.Equal(a, b);
}
Upvotes: 7
Views: 1697
Reputation: 81
Just use ValueObjects instead of primitives. Just as JonasH already said.
Make a new class named "CaseInsensitiveString" that implements IEquatable. The record will then use the Equals method.
Something like this:
public readonly struct CaseInsensitiveString : IEquatable<CaseInsensitiveString>
{
public readonly String StringValue;
public CaseInsensitiveString( string value )
{
StringValue = value;
}
public bool Equals( CaseInsensitiveString other)
{
return string.Equals( StringValue, other.StringValue, StringComparison.InvariantCultureIgnoreCase );
}
public static implicit operator string( CaseInsensitiveString h ) => h.StringValue;
public static implicit operator CaseInsensitiveString( string s ) => new CaseInsensitiveString(s);
}
Because of the implicit operators you can just use strings:
record MyKey(CaseInsensitiveString Foo, int Bar);
...
var a = new MyKey("ID", 42 );
See also: https://wiki.c2.com/?PrimitiveObsession`
Upvotes: 3