DavWEB
DavWEB

Reputation: 440

How to make records equality case-insensitive for strings?

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

Answers (1)

T1Space
T1Space

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

Related Questions