为什么这个C#重载和nullables没有歧义?

为什么这个C#重载和nullables没有歧义?,c#,compilation,overloading,C#,Compilation,Overloading,为什么C#允许以下方法重载: void F(int a) { Console.WriteLine(1); } void F(int? a) { Console.WriteLine(2); } 如果我运行该代码: A a = new A(); a.F(1); 它打印1。编译器如何知道调用哪一个。这不是模棱两可吗 我认为可空类型背后的想法是,您可以传入正确类型的值,或者传入null。因此,我应该能够使用(1)调用第一个F,使用(1)或(null)调用第二个F 我有一个可以运行的例子 更新: 在

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

void F(int a) { Console.WriteLine(1); }
void F(int? a) { Console.WriteLine(2); }
如果我运行该代码:

A a = new A();
a.F(1); 
它打印
1
。编译器如何知道调用哪一个。这不是模棱两可吗

我认为可空类型背后的想法是,您可以传入正确类型的值,或者传入
null
。因此,我应该能够使用
(1)
调用第一个
F
,使用
(1)
(null)
调用第二个
F

我有一个可以运行的例子

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


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

int?
实际上是一个可为null的结构,因此区分了两者

以下调用应打印
2

int? a = 0;
F(a);
关于以下电话

A a = new A();
a.F(1);
1
文本是一个
int
,而不是
int?
,因此它转到
void F(int a)
方法。如果要将
null
传递给该方法,则它不能是
int
,因此它将转到
void F(int?a)
方法,因为它是一个可能为null的数据类型


这两种方法都能够接受
1
值,但编译器将选择最具体的重载,在本例中,它是接受完全相同类型的重载,
int

,这绝对不是含糊不清的
Nullable
int
是两种不同的类型。不,这不是歧义,int!=int?@HimBromBeere是否重试?不确定出了什么问题。@P.Brian.Mackey补充了一个解释。我想当你这么说的时候,它是有道理的。它们当然是不同的类型。但是您不必传入类型为
Nullable
的值,对吗?我可以传入
1
,它将把它变成一个
null
1
文本的类型是
int
。因为有一个重载正好采用这种类型——它比另一个重载更可取,您的参数(类型
int
)可以隐式转换为这种类型。这是很常见的,例如,如果有
int
object
的重载,也会发生同样的情况。