当前位置:  开发笔记 > 编程语言 > 正文

在.Net/C#中,是否为强类型?

如何解决《在.Net/C#中,是否为强类型?》经验,为你挑选了2个好方法。

是否null有型?如何在内部表示空值?以下代码中发生了什么?

void Foo(string bar) {...}
void Foo(object bar) {...}

Foo((string)null);

编辑:迄今为止的答案都是非特定的,而且太高级了.我知道引用类型对象由堆栈上的指针组成,指针指向堆上的一个位置,该位置包含同步块索引,类型句柄和对象的字段.当我设置一个对象的实例时,null堆栈上的指针指向哪里?而在代码片段,仅仅是使用C#编译器来决定哪些超载致电剧组,并没有真正空的事情进行任何造型?

我正在寻找了解CLR内部人员的深入答案.



1> Greg Beech..:

演员到string您的代码示例中没有给出null一个类型,null不能有类型本身.如果你想要证明这一点,那么执行下面的代码,你可以看到它null总是等于它自己,不管它被赋给的变量类型是什么:

string s = null;
IPAddress i = null;
Console.WriteLine(object.Equals(s, i)); // prints "True"
Console.WriteLine(object.ReferenceEquals(s, i)); // prints "True"

演员所做的是告诉编译器选择哪个重载.由于null没有类型,它不知道是否选择带有objecta或a 的重载,string因为该值可以被解释为.因此,您可以通过说"这是一个应该被视为字符串的空值"来帮助它.


如果你想看看下面发生了什么,那么从代码中查看IL.方法调用的相关位在文本IL中类似于以下内容(取决于您的命名空间和类名等):

ldnull 
call void ConsoleApplication1.Program::Foo(string)

所有发生的事情是在堆栈上加载null,然后由占用字符串的重载消耗,因为在编译时执行重载解析,因此调用的方法被烘焙到IL中.

如果你想看看是什么ldnull,以及为什么它只是使用类似的东西ldc.i4.0将零加载到堆栈上然后看到这个答案(如果你不想跟随链接,原因是它是一个与大小无关的零否则在CLR中不存在).



2> Rui Craveiro..:

null没有类型,并且"在代码片段中,C#编译器只是使用它来决定调用哪个重载,并且实际上没有任何转换为​​null?" 正是这样.让我们看一下生成的IL.

  IL_0001:  ldnull
  IL_0002:  call       void ConsoleApplication1.Program::Foo(string)

注意ldnull将null加载到堆栈.它只是null,不是作为字符串或其他东西的null.重要的是第二行,其中IL显式调用接收字符串的重载.如果你打电话给对象,会发生以下情况:

  IL_0001:  ldnull
  IL_0002:  call       void ConsoleApplication1.Program::Foo(object)

所以,是的,强制转换是一个C#工件,因此编译器知道要调用的重载.

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有