在运算符重载的情况下,C#编译器如何决定哪种实现适用于混合类型的操作数?

int normal;
int? nullable;
var x = normal/nullable; // expression evaluates to Nullable<int>
var y = nullable/normal; // also Nullable<int>

编辑:我原来的问题有点邀请我不想要的答案.标题实际上总结了这个问题,用来说明它的例子很难选.

在上面,编译器只有一种可能:int.divide运算符不支持可空int操作数,int?确实如此,并解决了这个问题.没有歧义,也不需要任何类型的预设规则.

但是,如果我有两种类型重载相同的运算符,例如除以示例,并且它们都支持另一种类型作为操作数之一?

这里有两个问题:

1)当两种类型都支持Type1 / Type2和Type2 / Type1时,编译器如何决定是使用Type1还是Type2的运算符?是否有从左到右的优先级(对于二进制操作)或其他什么?

2)对称性等操作是否有任何假设?换句话说,A B必须始终等于B A,还是那个类型?

最后,这些问题可能略显具有学术性,因为在许多实际场景中,任何方法的风格(无论是虚拟方法,普通实例方法,还是静态“实用”方法,即使后者最接近于运算符)都可以用于同样的结局.然后,可能存在这样的情况:通过使用运算符而不是常规方法语法来实现更容易阅读的语法,可以获得真正的价值. (语法是语言首先拥有运算符的唯一原因;它毕竟只是一种方法.)

最佳答案

how does the compiler decide that it’s the nullable type’s division operator and not the regular int’s operator that applies?

因为无法应用“常规”运算符.
这当然使用普通的运算符:

 var x = normal/nullable.Value;

但是当你将普通和可空结合起来时,可以考虑将nullable称为“unknnown”. x未知多少钱?它再次未知.并且因为结果可能为null,所以表达式的结果类型必须是可空的.

点赞