【发布时间】:2026-01-27 05:30:01
【问题描述】:
①在以下C#代码中,出现CS1729,但我知道CS0122会更合适。
namespace A
{
class Program
{
static void Main()
{
Test test = new Test(1);
}
}
class Test
{
Test(int i) { }
}
}
CS1729:“A.Test”不包含采用 1 个参数的构造函数
CS0122:'A.Test.Test(int) 由于其保护级别而无法访问'
②在以下C#代码中,出现CS0122,但我知道CS1729会更合适
namespace A
{
class Program
{
static void Main()
{
Test test = new Test();
}
}
class Test
{
Test(int i) { }
}
}
CS0122:'A.Test.Test(int) 由于其保护级别而无法访问'
CS1729:“A.Test”不包含采用 0 个参数的构造函数
问题:CS0122和CS1729在①和②中交换有什么原因还是这个C#编译器错误?
P.S.:①和②中的错误可以用 Microsoft Visual C# 2010 Compiler version 4.030319.1 重现。
【问题讨论】:
-
+1 我同意你的分析。有人会假设编译器会首先执行解析,然后检查可访问性。相反,它似乎首先过滤可访问性,然后检查匹配项。但是,出于性能原因,第二个可能更有意义(当然,完全取决于编译器内部)。
-
公平地说,这两种错误消息都适用于这两种情况。首先发现哪个以及编译器何时停止报告可能取决于内部算法。要求编译器选择“最好的”错误(在人眼中)可能是一座过分的桥梁。
-
只是猜测,但可能是因为 C# 默认会自动创建一个空构造函数,当您不传递参数时,编译器会假定使用了默认构造函数并首先检查可访问性。在第一个示例中,首先检查方法的解析可能被认为更有效,因为它不是类的默认行为。
-
@keyboardP 默认,当您显式声明任何其他构造函数时,编译器不会添加无参数。
-
@MarcinJuraszek - 确实,但我认为这可能是 when 编译器检查是否应添加默认值的情况。我对 C# 编译器了解不多,所以可能是一个疯狂的猜测(可能是:))
标签: c# constructor compiler-errors protection