gpt4 book ai didi

c# - Mono + 命名/可选参数 = 编译器错误?

转载 作者:行者123 更新时间:2023-11-30 21:18:03 25 4
gpt4 key购买 nike

我在移植到 mono 2.8.1 时遇到了一些无法预料的后果。问题可以归结为一个示例程序(在将几个类和约 1000 行代码剪切到下面引用的文件后,我无法进一步减少它)

public class Person
{
public Person(int age, string name = null){}
public Person(double income, string name = null){}
public Person(double income, int age, string name = null){}
}

class Program
{
static void Main()
{
Person p = new Person(1.0, name: "John Doe");
}
}

用 mcs 编译以上代码给出输出:

test.cs(22,24): error CS0584: Internal compiler error: Internal error
test.cs(22,20): error CS0266: Cannot implicitly convert type `object' to `NamedParams.Person'.
An explicit conversion exists (are you missing a cast?)
Compilation failed: 2 error(s), 0 warnings

删除可选/命名参数的使用(即调用 new Person(1.0, null, "John Doe") 或 new Person(1.0, null, name:"John Doe"),或 new Person(1.0, "John Doe"") ) 导致完美的编译。此外,在 VS2010 下,文件(以及我开始使用的整个解决方案)编译得很好。转换会移除错误 CS0266,但不会移除 CS0584——所以这不足为奇。

我的问题:是我做错了什么,还是 mcs(即 mcs 中的错误对我来说很明显——“内部错误”还有什么意思,但也许这样的程序无法编译也没关系),或者也许 VS2010 中的 Microsoft 编译器不应该让这样的代码编译?

我敢打赌是 mcs 错了(无法猜出正确的构造函数),但也许事实并非如此,我不应该知道得更多?

附言。我尝试在 Google 和 Novell 的 Bugzilla 中搜索类似这样的已知错误,但找不到任何相关内容。再一次,我可能是盲人;)

最佳答案

好的,开始了。崩溃确实是由于第三个过载,Person(double income, int age, string name = null)。编译器发现您尝试传递的参数少于签名中列出的参数,因此它会寻找可选参数。它高兴地注意到 name 是可选的,并假定您没有传递该参数。它通过在提供的参数末尾附加一个占位符来实现这一点。接下来,它会重新排序列表中的命名参数,以便它们最终位于正确的位置。这意味着 John Doe 现在正确地位于 name 的最后位置,但占位符进入了 age 位置。编译器然后尝试填充默认值,但震惊地发现在一个没有默认值的位置有一个占位符。它认为这不可能发生,因为占位符只是为可选参数添加的,现在突然间它不再是可选的了。不知道要做什么,它会抛出异常。

以下补丁似乎解决了这个问题(但它可能会破坏其他东西,所以不提供保证):

--- mono-2.6.7.orig/mcs/mcs/ecore.cs    2009-10-02 12:51:12.000000000 +0200
+++ mono-2.6.7/mcs/mcs/ecore.cs 2010-12-21 02:26:44.000000000 +0100
@@ -3803,6 +3803,15 @@

int args_gap = Math.Abs (arg_count - param_count);
if (optional_count != 0) {
+ // readjust for optional arguments passed as named arguments
+ for (int i = 0; i < arguments.Count; i++) {
+ NamedArgument na = arguments[i] as NamedArgument;
+ if (na == null)
+ continue;
+ int index = pd.GetParameterIndexByName (na.Name.Value);
+ if (pd.FixedParameters[index].HasDefaultValue)
+ optional_count--;
+ }
if (args_gap > optional_count)
return int.MaxValue - 10000 + args_gap - optional_count;

关于c# - Mono + 命名/可选参数 = 编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4495108/

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