C#和CLI在值类型和构造函数方面有什么区别?

8

最近我看到有报道称,C#和CLI标准定义了处理值类型和构造函数的不同方式。

根据CLI规范,值类型不能有无参数构造函数,而在C#规范中,值类型具有默认的无参数构造函数。如果按照CLI规范,您需要创建一个没有指定任何参数的值,那么可以使用特殊指令来完成这个功能。

因此,我的问题是:

  • 为什么C#设计人员会故意偏离CLI标准 - 这样做有什么好处,为什么CLI不允许这种功能?
  • 就我的有限经验而言,每当我发现自己使用“特殊指令”来允许最初并未打算的功能时,通常都有些不太对劲。这与其他情况有何不同?

你看过使用Reflector反编译的代码了吗? - Jonathan Allen
不,我没有具体的代码可供查看,我的问题是基于我读到的东西。 - DaveDev
你是从哪里看到这个的?我知道这是我多次指出的问题,但我没有看到其他人提到过。 - Jon Skeet
@Jon,实际上我是在你的书中读到的 - 我不想直接引用书中的内容,因为我认为这可能会影响问题的回答...就像沃伦·巴菲特最新的投资一旦被公布,股票立即飙升一样!希望你不介意。 - DaveDev
完全没有问题。我只是好奇 :) - Jon Skeet
3个回答

7

从一致性的角度来看,在各个地方,将值类型视为具有无参构造函数是有意义的。您可以在不提供任何参数的情况下创建值类型,这在CLI和C#中都是正确的。在C#中,您可以使用标准的构造函数语法:

int x = new int();

与其存在一种语法用于这个目的,另一种语法用于调用“真正”的构造函数,不如采用一种统一的语法。

请注意,从C# 2开始,有一个默认值运算符,我想这个运算符也可以被使用:

int x = default(int);

这感觉更接近生成的IL代码。我想,如果一开始就有这个,C#可能就不会“假装”所有值类型都有无参构造函数了。

另一方面,考虑泛型:

public void Foo<T>() where T : new()
{
    T t = new T();
}

对于值类型,是否应该允许这样做?是的,但如果C#不允许 new int() ,那么在通用形式中允许它就没有太多意义了...

你可能想要更深入地了解一个有趣的观点 - 尽管C#不允许您定义自定义值类型无参数构造函数,但您可以在IL中这样做,并且C#会根据上下文情况有时使用它(有时不使用)。请参阅我的博客文章以获取更多详细信息


0
在 C# 规范中,值类型具有默认的无参数构造函数,这是不可更改的。因此,效果是相同的,只是定义方式不同而已。

0
值类型和类类型之间的一个重要区别是,类类型实例(与值类型实例相反)只能通过调用构造函数来创建,并且只有在构造函数完成或显式地公开正在构建的对象之后才会暴露给外部世界。相比之下,值类型实例将通过创建具有值类型字段的封闭结构体或类类型实例,或通过创建值类型元素数组而被创建出来。虽然微软完全可以允许为结构定义显式无参数构造函数,但很难确保每个结构都在暴露给外界之前运行其无参数构造函数,并且在某些情况下运行此类构造函数会令人困惑。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接