14

I have a vector class with two deconstruction methods as follows:

public readonly struct Vector2
{
    public readonly double X, Y;

    ...

    public void Deconstruct( out double x, out double y )
    {
        x = this.X;
        y = this.Y;
    }

    public void Deconstruct( out Vector2 unitVector, out double length )
    {
        length = this.Length;
        unitVector = this / length;
    }
}

Somewhere else I have:

Vector2 foo = ...
(Vector2 dir, double len) = foo;

This gives me:

CS0121: The call is ambiguous between the following methods or properties: 'Vector2.Deconstruct(out double, out double)' and 'Vector2.Deconstruct(out Vector2, out double)'

How is this ambiguous?

Edit: Calling Deconstruct manually works fine:

foo.Deconstruct( out Vector2 dir, out double len );
  • If your Vector class had implicit conversion to/from a double, say, then this would be ambiguous. – Ian Mercer Apr 19 at 20:28
15

This is by design in C#. Overloads of Deconstruct must have different arity (number of parameters), otherwise they are ambiguous.

Pattern-matching does not have a left-hand-side. More elaborate pattern-matching scheme is to have a parenthesized list of patterns to match, and we use the number of patterns to decide which Deconstruct to use. - Neal Gafter https://github.com/dotnet/csharplang/issues/1998#issuecomment-438472660

  • 3
    That is thoroughly disappointing! – Chris Apr 19 at 20:13
  • @Chris Yeah, looks like they decided to not use the type declarations for overload resolution in part so the type declarations can use var. – Nat Apr 20 at 6:12
  • Generally speaking, in left = right;, the type of left is determined by the type of right, not the other way around. It's no different here. – Asik Apr 20 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.