什么是默认值,为什么不能覆盖?

在执行代码审查时,我找到了可以通过使用Null对象模式来减少潜在错误的代码。 然后我开始思考:如果该业务对象的默认值是空对象而不是空引用,那会不会有用?

由于C#提供了默认运算符,我试图像这样重载它:

public static MyObject operator default (MyObject object) { return MyObject.Null; } 

这给了我错误:’可加载的一元运算符’。 在进一步挖掘时,我发现文档的一部分说默认(T)是主要操作符:可重载操作符 。

当你在上面的页面上实际点击默认值(T)时,默认是一个关键字。

最重要的是,此页面并未说默认值不可重载:可重载运算符(C#编程指南) 。

我知道这是一种学术,但我试图更深入地理解语言。 什么是默认值(T)? 它是运营商还是关键字? 为什么不能超载(从语言设计的角度来看)?

更新:是的我已阅读C#语言规范第7.5.13节,我知道该语言的作用。 我想知道为什么。

重载default会使C#和运行时的设计显着复杂化。 目前,假设任何值类型的二进制清零都是有效的,并且等效于该值类型的default值。 对于引用, null引用始终有效,并且等效于任何引用类型的default

这允许运行时开始在二进制零状态的对象上运行构造函数并获得理智的行为。

CodeInChaos的答案基本上是现货。 一些额外的想法。

假设你制作了一千个对象的数组。 是否应将新分配的数组的每个元素初始化为默认值? 操作员应该被调用一千次吗?

如果操作员在不同时间返回不同的值,该怎么办?

如果操作员抛出exception怎么办?

在那种情况下,可以观察到部分初始化的对象处于“预默认值”状态吗?

假设MyObject.Null是一个字段。 默认运算符运行之前字段的值是多少? 那可以观察到吗? 你可以进入无限循环,尝试将MyObject.Null设置为默认值,即MyObject.Null吗?

等等。 这些是语言设计者在考虑这样的function时必须处理的各种问题。 大多数时候,解决方案是不做function而不是试图找出所有这些棘手问题的答案。

谢谢你指出文档不足; 我会向文档管理员提一下。

要回答您的其他问题:

C#中有三种“默认”用法。

“默认”运算符是运算符。 它是一个运算符,其参数必须是类型的名称,如“typeof”运算符或“sizeof”运算符。 此function是在C#2.0中添加的,因为当您在类型系统中使用generics时它非常方便。

“default”也可用于标记switch语句的默认情况。

最后,“default”可以用作“预处理器”指令的一部分。

“default”是C#语言的保留关键字,自C#1.0以来就是这样。

然后我开始思考:如果该业务对象的默认值是空对象而不是空引用,那会不会有用?

听起来你的项目将受益于使用一个IOC容器,它可以默认注入一个NullBusinessObject实例,它可以做任何你想要它做的默认行为。 C#本身并不提供任何可以在这方面覆盖的内置内容。

default(T)通常“zeros-out”为类创建一个空引用,并为值类型(C#中的struct)创建一个清零版本。 default是C#中的关键字和MSIL中的运算符。 C#不允许覆盖默认值。