强制转换 null 不会编译
本文关键字:编译 null 转换 | 更新日期: 2023-09-27 18:21:29
>无意中,我写了以下代码行:
string x = (object) null;
// It was var x = (object)null and I changed from var to string instead of
// object x = null;
这给了我一个类似于这样的编译错误:Can't cast source type object to target type string
为什么?null
不就是一堆指向"无处"内存地址的零,无论类型是什么吗?
问题不在于null
的铸造,而在于object
不能分配给string
。 这工作正常
string x = (string)null;
删除强制转换(string x = null
(的工作原理在C#语言规范的第2.4.4.6节中列出
null文本可以隐式转换为引用类型或可为 null 的类型
当你引入一个强制转换((object)null
(的那一刻,你不再有一个空文本。 相反,您有一个类型 object
的值。 它本质上与
object temp = null;
string x = temp;
这里的问题基本上是"为什么编译器不考虑它知道分配的值是已知为 null 的常量引用这一事实?
答案是:为什么要这样做?考虑这些信息有什么令人信服的好处?您故意说"我希望将此表达式视为对象类型",并且不能将 object 类型的值分配给字符串类型的变量。在这种情况下允许这样做有什么好处?
在我看来,代码很可能是一个错误;当然,编译器应该告诉你它,而不是允许它。
null 不就是一堆指向"无处"内存地址的零,无论类型是什么吗?
这就是像 C 或 C++ 这样的弱类型语言的全部内容。
在 C# 中,引用的类型是其标识的组成部分。 (string)null
与(object)null
不是一回事,因为一个是string
,一个是object
。
此外,在 C# 中,null
实际上没有等效的数字。 C# 中的引用与指针不同,从语义上讲,它们没有关联的内存地址。 null
只是意味着引用不指向对象,null
引用的内部表示形式是实现细节。
它需要可分配 - 即使它看起来是"相同的 null"并且无关紧要,编译器仍然维护该类型。这样做的一个优点是解决重载问题:
void Foo(object bar) { ... }
void Foo(string bar) { ... }
Foo((object)null); // will call the former
Foo((string)null); // will call the latter
也许object x = (string) null;
这可能有效,但你为什么要这样做呢?
,但字符串不能容纳对象
字符串是从对象继承的,而不是相反。
您可以将 null 赋值给引用类型的任何变量,而无需强制转换任何内容:
String x = null;
每个类都有一个定义列表:
Constructors
Destructors
Fields
Methods
Properties
Indexers
Delegates
Events
Nested Classes
Object 是一种泛型类型,因为每个类都是从它继承的,而不是以其他方式继承的。这些定义对于每个类都不相同,因此编译器可以决定可以相互分配/强制转换哪些类型。
然后你做:string x = (object)null;
编译器并不关心你首先尝试分配给x的值,但它会检查字符串的类型定义,只是不让你射击自己的腿,并生成错误,因为它是类型不匹配。