gpt4 book ai didi

C#解构和重载

转载 作者:太空狗 更新时间:2023-10-29 20:22:55 25 4
gpt4 key购买 nike

在研究 C# 7.x 中的新功能时,我创建了以下类:

using System;
namespace ValueTuples
{
public class Person
{
public string Name { get; }
public DateTime BirthDate { get; }

public Person(string name, DateTime birthDate)
{
Name = name;
BirthDate = birthDate;
}

public void Deconstruct(out string name,
out int year, out int month, out int day)
{
name = Name;
year = BirthDate.Year;
month = BirthDate.Month;
day = BirthDate.Day;
}

public void Deconstruct(out string name,
out int year, out int month,
out (int DayNumber, DayOfWeek DayOfWeek) day)
{
name = Name;
year = BirthDate.Year;
month = BirthDate.Month;
day.DayNumber = BirthDate.Day;
day.DayOfWeek = BirthDate.DayOfWeek;
}
}
}

和下面的测试代码:

using System;
namespace ValueTuples
{
class MainClass
{
static void Main()
{
var dh = new Person("Dennis", new DateTime(1985, 12, 27));
// DECONSTRUCTION:
(string name, _, _, (_, DayOfWeek dow)) = dh;
Console.WriteLine($"{name} was born a {dow}");
}
}
}

如果 Person 类仅包含 SECOND Deconstruct 重载,则代码可以正常编译和运行(“丹尼斯出生于星期五”)。但是一旦将第一个重载添加到 Person,编译器就会开始报错,错误消息是:

The call is ambiguous between the following methods or properties: 'Person.Deconstruct(out string, out int, out int, out int)' and 'Person.Deconstruct(out string, out int, out int, out (int DayNumber, DayOfWeek DayOfWeek))' (CS0121) (ValueTuples)

我已阅读 MSDN 和 GitHub 文档,但我不清楚为什么编译器无法确定唯一适用的重载是第二个,因为赋值左侧有内部元组模式。如有任何澄清,我们将不胜感激。

最佳答案

要了解发生了什么,重要的是要记住表达式中的:

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

(_, DayOfWeek dow) 部分不是元组。这是第二次解构。因此,编译器无法选择只使用第二个 Deconstruct 来满足五个参数(通过将元组解构为最后两个参数),还是从第一个参数中获取 day 参数一个,然后尝试在 int 上找到一个 Deconstruct 来满足该部分。

要查看实际效果,请注释掉第二个 Deconstruct,然后添加:

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

此时,代码再次编译正常。

对元组和解构使用相同的语法会带来很多好处。正如您所发现的那样,当您将两者混合使用时它有缺点,因为编译器无法知道您希望 (_, DayOfWeek dow) 成为解构中的元组,当它是有效的解构时语法。

但是,编译器选择使用哪个 Deconstruct 的行为似乎仍然存在严重限制,即使它提供了足够的类型信息来解析表达式。它采用一种非常简单的方法来匹配元数(参数数量)。因此,如果存在两个具有相同数量参数的 Deconstruct 方法,则无法在它们之间进行选择。例如,

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

应该工作得很好,因为我们已经告诉它第四个参数的类型,因此现在只有一个 Deconstruct 匹配。但它仍然提示无法在两者之间做出选择。 I've therefore raised an issue with the C# team看看是否可以在该语言的 future 版本中对此进行改进。

关于C#解构和重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47195668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com