Skip to content

Operators not working as expected #9

@shuebner

Description

@shuebner

Hey there,
I have been playing around a bit with domain primitives myself for a while now and had a problem with preserving the domain primitive type (TThis in your repo) and the equals and not-equals operators. So, I had a look at your ValueOf and noticed the same problem, namely that the == and != do not work as expected in some situations, i. e. they are not even called when TValue is the same, but TThis is different.

The following tests fail, because the compiler implicitly converts john1 and john2 to string before applying ==, making it look like two instances of different domain primitive types are equal.

public class ValueOfTestsMinimal
{
    [Fact]
    public void OperatorEquals_When_types_are_different_and_underlying_value_is_same_Then_returns_false()
    {
        FirstName john1 = FirstName.From("John");
        LastName john2 = LastName.From("John");

        var isEqual = john1 == john2;

        isEqual.Should().BeFalse();
    }

    [Fact]
    public void OperatorNotEquals_When_types_are_different_and_underlying_value_is_same_Then_returns_true()
    {
        FirstName john1 = FirstName.From("John");
        LastName john2 = LastName.From("John");

        var isEqual = john1 != john2;

        isEqual.Should().BeTrue();
    }

    private class FirstName : ValueOf<string, FirstName>
    {
    }

    private class LastName : ValueOf<string, LastName>
    {
    }
}

Is that by design? Because I think this is very unexpected and easily overlooked.
And yet there is a test expecting == to return true for a domain primitive and a string.

Adding another overload seems to fix the problem:

    public static bool operator ==(ValueOf<TValue, TThis> a, object b) =>
            b is TThis other && a == other;

    public static bool operator !=(ValueOf<TValue, TThis> a, object b) =>
            !(a == b);

What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions