0

I have the following two structs representing coordinates in a 2D matrix:

readonly struct Coordinates
{
    public Coordinate X { get; }
    public Coordinate Y { get; }

    public Coordinates(Coordinate x, Coordinate y)
    {
        X = x;
        Y = y;
    }

    public static implicit operator (Coordinate x, Coordinate y)(Coordinates c)
    => (c.X, c.Y);

    public static implicit operator Coordinates((Coordinate x, Coordinate y) c)
    => new Coordinates(c.x, c.y);

    public void Deconstruct(out Coordinate x, out Coordinate y)
    {
        x = X;
        y = Y;
    }

    public void Deconstruct(out int x, out int y)
    {
        x = X;
        y = Y;
    }
}

readonly struct Coordinate
{
    private int Value { get; }

    public Coordinate(int value)
    {
        if (value < 0)
            throw new ArgumentException(nameof(value));

        Value = value;
    }

    public static implicit operator int(Coordinate c)
    => c.Value;

    public static implicit operator Coordinate(int value)
    => new Coordinate(value);
}

When I try to use positional pattern matching like this:

static void Test()
{
    object o = null;
    if (o is Coordinates(var x, 5))
    {
        Console.WriteLine(x);
    }
}

I get the error:

The call is ambiguous between the following methods or properties: 'Coordinates.Deconstruct(out Coordinate, out Coordinate)' and 'Coordinates.Deconstruct(out int, out int)'

Since the first parameter in the pattern is an int, it shouldn't be ambiguous, shouldn't it? What am I missing? If it's just a limitation of the language: What be an elegant way around this issue?

Tim Pohlmann
  • 4,140
  • 3
  • 32
  • 61
  • 1
    But you have implicit operator to convert `int` to `Coordinate` and vise versa – Pavel Anikhouski Jan 17 '20 at 19:33
  • @PavelAnikhouski that makes sense... didn't think about that :D Any suggestion for an elegant solution? – Tim Pohlmann Jan 17 '20 at 19:35
  • Have a look at this [thread](https://stackoverflow.com/questions/55767219/deconstruction-is-ambiguous), it isn't allowed to have multiple deconstruct methods with the same numbers of parameters – Pavel Anikhouski Jan 17 '20 at 19:39
  • I don't think it should be a `ambiguous` because `5` is a `int`-type value, so the `int` overload should be prior to any other overloads with implicit conversions. This should be posted as an issue on the [C# design repository](https://github.com/dotnet/csharplang/issues) – Alsein Feb 12 '20 at 05:12
  • @Alsein as Pavel pointed out it works as designed. You cannot have multiple deconstructors with the same numbers of parameters. – Tim Pohlmann Feb 12 '20 at 07:55

0 Answers0