在类和结构之间进行选择

fwe*_*end 6 polymorphism struct d class

关于C#的msdn文章命名为在类和结构之间选择,给出了以下建议:

如果类型的实例很小并且通常是短暂的或者通常嵌入在其他对象中,则考虑定义结构而不是类.

除非类型具有以下所有特征,否则不要定义结构:

It logically represents a single value, similar to primitive types
Run Code Online (Sandbox Code Playgroud)

(整数,双精度等).

It has an instance size smaller than 16 bytes.

It is immutable.

It will not have to be boxed frequently. 
Run Code Online (Sandbox Code Playgroud)

如果不满足这些条件中的一个或多个,请创建引用类型而不是结构.不遵守本指南可能会对性能产生负面影响.

我想知道在D的情况下答案是什么.到目前为止,我只是在我不需要多态的情况下使用结构.我不知道尺寸是否也是一个考虑因素.或其他任何东西.

dsi*_*cha 8

在D中,与C#有一些关键的区别,使得它struct更经常使用:

  1. 没有自动装箱,因为它解决的问题通常通过模板解决.

  2. 现在,垃圾收集器的效率较低.

  3. 如果你想要引用语义,在大多数情况下,结构的指针运行良好.(唯一的主要的例外是指向具有重载算术或索引操作符结构古怪的行为,因为操作被作为指针运算,而不是调用操作符重载处理的).此外,结构可以很容易地使用在堆上分配new操作.

  4. 结构可以有确定性的析构函数(不是终结符),复制构造函数等,所以你可以像在C++中那样用它们做类似的魔术.

我会说一个结构应该在你不需要多态时使用,以后不需要它,不需要引用语义,或者你需要确定性破坏,复制构造等等.如果你需要多态性那么你肯定需要使用一堂课.

如果您不需要多态但需要引用语义,则指向堆分配结构或最终类的指针可以正常工作.最后一个类在语法上稍微好一些,并且在重载算术运算符时不会遇到奇怪的角点情况.结构通过没有vtable或监视器来避免几个字节的开销.如果这些都不重要,那么这只是个人偏好的问题.


Jon*_*vis 7

我要说的是,这个建议肯定不会适用D.

结构是值类型.类是引用类型.结构通常在堆栈上(尽管它们可以在堆上并用指针指向).类在堆上.结构没有继承或多态.类具有继承和多态性.

在D中使用结构是常见的.我认为一般规则是,如果某些东西不需要具有多态性,那么它应该是一个结构.的主要理由选择在结构一类是因为你要继承和多态.

第二个原因是如果它更适合作为引用类型的类型(例如,容器应该是一个类,因为每次将它传递给函数时复制它都不会很好).结构可以具有引用语义,但是为此使用类更简洁.

最后,如果一个类型中包含大量数据,并且每当你将它传递给一个函数时都不需要它的副本,那么将它作为一个类并且只在你复制它时会更有效率实际上需要(尽管你可以选择总是通过ref传递它).

D的结构肯定比C#的结构更漂亮,因为它们有析构函数和postblit构造函数.D中也没有自动装箱问题,因为D使用模板(类似于C++,虽然功能更强大,更易于使用),而不是泛型.如果你需要一个指向结构的指针,那很容易做到.所以,我真的不认为C#的建议适用于D.

在我看来,C#建议源于两个问题:

  1. 结构是值类型,因此具有值语义.
  2. 事实上,C#中的结构必须处理自动装箱,并且必须非常担心复制的成本.

结构也是d值类型,但如果你想他们足够强大,能够有引用语义,并增设postblit构造函数和析构函数使其成为有用的远远超过你可以在C#结构做什么.由于D没有自动装箱,因此对自动装箱的担忧不适用于D.你仍然不希望你的结构很大,因为除非你通过参考,否则每当你通过它们时它们都会被复制一个函数,但它绝对不像C#中那么大.在这方面,它更符合C++.

而关于不变性的建议并不适用于所有到D d结构是经常可变的,如果他们不是这将是一个很大的问题.例如,范围通常作为结构实现,如果你不能改变它们,这是不可能的.

所以,不,我不认为C#建议真的适用于D.两种语言之间的情况太不同了.最好将D的结构视为C++类,它们没有任何基类,也不能从中派生出来,因为它比C#的结构更接近实际的结构.