为什么这个C#重载与nullables不模糊?

pus*_*kin 3 c# overloading compilation

为什么C#允许以下方法重载:

void F(int a) { Console.WriteLine(1); }
void F(int? a) { Console.WriteLine(2); }
Run Code Online (Sandbox Code Playgroud)

如果我运行该代码:

A a = new A();
a.F(1); 
Run Code Online (Sandbox Code Playgroud)

它打印1.编译器如何知道要调用哪一个.不是很暧昧吗?

我认为可以为空的类型背后的想法是你可以传递正确类型的值,或者你可以传入null.所以我应该能够调用第一F(1)和第二F(1)(null).

这里有一个可运行的例子.

更新: 在阅读答案之后,我的困惑源于这样一个事实:我认为可以为空的params是可选参数的同义词.

实际上,替换第二种方法void F(int a = 0);会导致编译错误.

St.*_*Pat 8

int?实际上是一个Nullable<int>结构,所以区分两者.

应打印以下调用 2

int? a = 0;
F(a);
Run Code Online (Sandbox Code Playgroud)

关于以下电话......

A a = new A();
a.F(1);
Run Code Online (Sandbox Code Playgroud)

1文字是int,不是int?,如此这般的void F(int a)方法.如果你要传递null给方法,它不能是一个int,所以它转到void F(int? a)方法,因为它是一个可以为null的数据类型.

两种方法都能够接受该1值,但编译器将选择最具体的重载,在这种情况下,是接受完全相同类型的重载int.