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

时间:2011-06-24 19:24:23

标签: c#

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

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

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

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

当您在上一页上实际点击默认(T)时,它表示默认为关键字。

最重要的是,此页面并未说默认值不可重载:Overloadable Operators (C# Programming Guide)

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

更新:是的我已阅读C#语言规范第7.5.13节,我知道该语言的作用。我想了解原因。

4 个答案:

答案 0 :(得分:17)

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

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

如果操作员在不同时间返回不同的值会怎样?

如果操作员抛出异常怎么办?

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

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

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

感谢您指出文档不足;我会向文档管理员提及。

回答您的其他问题:

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

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

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

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

“default”是C#语言的保留关键字,自C#1.0以来就一直存在。

答案 1 :(得分:15)

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

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

答案 2 :(得分:2)

  

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

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

答案 3 :(得分:1)

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