C# deconstruction and overloads

喜夏-厌秋 提交于 2019-11-29 13:59:41

To understand what's going on, it's important to remember that in the expression:

(string name, _, _, (_, DayOfWeek dow))

the (_, DayOfWeek dow) part is not a tuple. It's a second deconstruct. So the compiler cannot choose between just using your second Deconstruct to satisfy the five parameters (via deconstructing the tuple to the last two parameters), or taking the day parameter from the first one and then attempting to find a Deconstruct on int to satisfy that part.

To see this in action, comment out the second Deconstruct, then add:

static class MyDeconstruct
{
    public static void Deconstruct(this int i, out int dayNumber, out DayOfWeek dayOfWeek) =>
        (dayNumber, dayOfWeek) = (i, (DayOfWeek)i);
}

At that point, the code once again compiles just fine.

Using the same syntax for tuples and deconstructs brings many advantages. As you have discovered though, it has the disadvantage when you mix the two as the compiler has no way of knowing you want (_, DayOfWeek dow) to be a tuple in your deconstruct, when it's valid deconstruct syntax.

However, there still seems to be a severe limitation to the behaviour of compiler to choose which Deconstruct to use, even when it's provided with sufficient type information to resolve the expression. It takes a very simple approach of matching the arity (number of parameters) only. So if two Deconstruct methods exist with the same number of parameters, it can't choose between them. For example,

(string name, _, _, int day) = dh;

ought to work just fine as we have told it the type of the fourth parameter and thus there is now only one Deconstruct that matches. Yet it still complains it can't choose between the two. I've therefore raised an issue with the C# team to see if that can be improved in a future version of the language.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!