CLR问题。为什么C#中的方法重载决定null是一个字符串?

时间:2009-10-29 05:50:09

标签: c# clr

  

可能重复:
  C#: Passing null to overloaded method - which method is called?

这是一个测试用例

object a = null;
var b = Convert.ToString (null);
var c = Convert.ToString (a);
string d = Convert.ToString (null); // CLR chooses Convert.ToString(string value)
string e = Convert.ToString (a); // CLR chooses Convert.ToString(object value)

问题是为什么CLR在第一种情况下决定将null解释为字符串? 此问题似乎已经回答here

这是另一个类似的案例。这些ifs都没有被触发

object x = null;
if (x is object)
{
    Console.Write ("x is object");
}

if (x is string)
{
    Console.Write ("x is string");
}

if (null is object)
{
    Console.Write ("null is object");
}

if (null is string)
{
    Console.Write ("null is string");
}

2 个答案:

答案 0 :(得分:2)

答案是因为它必须选择一个引用类型(null不适用于值类型),每个string都是object,但不是每个object都是{ {1}}。 See Jon Skeet's answer to this question for more information.

作为对第二个示例的回应,如果将一个null变量传递给string,则无论如何都会将其评估为false。

答案 1 :(得分:0)

在重载决策中,当面对选择将参数解析为基类或派生类时,编译器将始终选择最适合的派生类。这样可以实现重载,这种重载使得派生类不会因为带有基类的重载而变得模糊。在这种情况下,由于字符串是从对象中删除的,因此首选字符串。

有关详细信息,请参阅C# Language Specification中的第7.4.3节。那里有一个非常复杂的讨论,但基本的想法是,编译器使用一种算法来定义“最佳”的重载,其中一个比另一个更好的是:

  

•至少有一个论点,   从EX到PX的转换更好   而不是从EX到QX的转换。

阅读:

  

•如果从T1隐式转换为   T2存在,没有隐式转换   从T2到T1存在,C1更好   转换。

由于存在从任何派生类到其基类的隐式转换,但反之亦然,上述规则意味着任何匹配的衍生类重载总是在重载中击败基类参数。