在类和结构之间进行选择

发布于 2024-11-27 14:49:44 字数 528 浏览 0 评论 0原文

一篇有关 C# 的 msdn 文章在类和结构之间进行选择给出了以下建议:

如果以下情况的实例,请考虑定义结构而不是类 类型较小且通常寿命较短或通常嵌入 其他对象。

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

逻辑上表示单个值,类似于原始类型

(整数、双精度数等)。

它的实例大小小于 16 字节。

它是不可改变的。

它不必经常装箱。 

如果不满足其中一个或多个条件,请创建参考 类型而不是结构。不遵守本指南可能会 对性能产生负面影响。

我想知道在 D 的情况下答案是什么。到目前为止,我在不需要多态性的所有情况下都简单地使用了结构。不知道尺寸是否也是一个考虑因素。或者其他什么。

A msdn article on C# named Choosing Between Classes and Structures gives the following advice:

Consider defining a structure instead of a class if instances of the
type are small and commonly short-lived or are commonly embedded in
other objects.

Do not define a structure unless the type has all of the following
characteristics:

It logically represents a single value, similar to primitive types

(integer, double, and so on).

It has an instance size smaller than 16 bytes.

It is immutable.

It will not have to be boxed frequently. 

If one or more of these conditions are not met, create a reference
type instead of a structure. Failure to adhere to this guideline can
negatively impact performance.

I wonder what the answer would be in the case of D. So far I've simply used structs in all cases where I didn't need polymorphism. I don't know if size is also a consideration. Or anything else.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

绝對不後悔。 2024-12-04 14:49:44

在 D 中,与 C# 存在一些关键差异,这使得更频繁地使用 struct 成为惯用做法:

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

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

  3. 如果您需要引用语义,则在大多数情况下,指向结构的指针都可以很好地工作。 (唯一的主要例外是,指向具有重载算术或索引运算符的结构的指针表现得很奇怪,因为这些操作被视为指针算术而不是调用运算符重载。)此外,可以使用 new 轻松地对结构进行堆分配> 运算符。

  4. 结构可以具有确定性析构函数(不是终结器)、复制构造函数等,因此您可以像在 C++ 中一样使用它们执行类似的魔法。

我想说,只要你不需要多态性,将来也不需要它,也不需要引用语义,或者你需要确定性破坏、复制构造等,就应该使用结构体。如果你需要多态性,那么你肯定需要使用一个类。

如果您不需要多态性但需要引用语义,那么指向堆分配结构的指针或最终类都可以很好地工作。最终类在语法上稍微好一点,并且在重载算术运算符时不会遇到奇怪的极端情况。结构体由于没有虚函数表或监视器而避免了一些字节的开销。如果这些对您都不重要,那么这只是个人喜好问题。

In D, there are a few key differences from C# that make it idiomatic to use struct more frequently:

  1. There's no autoboxing because the problems it solves are typically solved with templates.

  2. Right now, the garbage collector is less efficient.

  3. Pointers to structs work well in most cases if you want reference semantics. (The only major exception being that pointers to structs with overloaded arithmetic or indexing operators behave weirdly because the operations are treated as pointer arithmetic instead of calling operator overloads.) Furthermore, structs can easily be heap allocated using the new operator.

  4. Structs can have deterministic destructors (not finalizers), copy constructors, etc., so you can do similar kinds of magic with them as in C++.

I'd say a struct should be used anytime you don't need polymorphism and won't need it in the future and don't need reference semantics, or if you need deterministic destruction, copy construction, etc. If you need polymorphism then you definitely need to use a class.

If you don't need polymorphism but want reference semantics then either a pointer to a heap-allocated struct or a final class would work well. A final class is slightly nicer syntactically and doesn't run into weird corner cases when overloading arithmetic operators. A struct avoids a few bytes of overhead by not having a vtable or a monitor. If neither of these are important to you then it's just a matter of personal preference.

未蓝澄海的烟 2024-12-04 14:49:44

我想说这个建议绝对不适用于 D。

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

在 D 中使用结构体非常常见。我认为一般规则是,如果某事物不需要具有多态性,那么它应该是结构体。选择类而不是结构的主要原因是因为您需要继承和多态性。

第二个原因是,如果类型成为引用类型更有意义(例如,容器可能应该是一个类,因为每次将其传递给函数时都复制它并不好)。结构可以具有引用语义,但使用类来实现这一点更加清晰。

最后,如果一个类型包含大量数据,并且每次将其传递给函数时都不需要复制它,那么将其设为类并仅在您传递时复制它会更有效。实际上需要(尽管您可以选择始终通过引用传递它)。

D 的结构肯定比 C# 的结构更精美,因为它们有析构函数和 postblit 构造函数。 D 中也不存在自动装箱问题,因为 D 使用模板(类似于 C++,尽管更强大且更易于使用)而不是泛型。如果您需要一个指向结构的指针,这很容易做到。所以,我真的不认为 C# 的建议适用于 D。

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

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

结构体也是 D 中的值类型,但它们足够强大,可以根据需要拥有引用语义,并且添加 postblit 构造函数和析构函数使它们的用处远远超出您的用途。可以使用 C# 中的结构。由于 D 没有自动装箱,因此有关自动装箱的担忧不适用于 D。您仍然不希望结构体很大,因为除非您通过 ref 传递,否则每当您传递它们时它们都会被复制到一个函数,但它绝对不像在 C# 中那样是一个大问题。在这方面它更符合 C++。

关于不变性的建议根本不适用于 D。D 结构经常是可变的,如果不可变,那将是一个大问题。例如,范围通常作为结构实现,如果不能改变它们,这是不可能的。

所以,不,我认为 C# 的建议并不真正适用于 D。这两种语言之间的情况实在是太不同了。最好将 D 的结构视为没有任何基类且无法派生的 C++ 类,因为这比 C# 的结构更接近它们的实际情况。

I would say that that advice definitely does not apply to D.

Structs are value types. Classes are reference types. Structs are normally on the stack (though they can be on the heap and pointed to with pointers). Classes are on the heap. Structs have no inheritance or polymorphism. Classes have inheritance and polymorphism.

It is very common to use structs in D. I think that the general rule is that if something doesn't need to have polymorphism, it should be a struct. The primary reason to choose a class over a struct is because you want inheritance and polymorphism.

The second reason would be if it just makes more sense for the type to be a reference type (e.g. a container should probably be a class, since copying it every time that you pass it to a function wouldn't be good). Structs can have reference semantics, but it's just cleaner to use classes for that.

And lastly, if a type has a lot of data in it and you don't need to have a copy of it whenever you pass it to a function, then it would be more efficient to make it a class and only copy it when you actually need to (though you can choose to just always pass it by ref instead).

D's structs are definitely fancier than C#'s structs, since they have destructors and postblit constructors. There are also no autoboxing issues in D, since D uses templates (similar to C++, albeit much more powerful and much easier to use) rather than generics. And if you need a pointer to a struct, it's easy to do. So, I really don't think that the advice for C# applies to D.

It seems to me that the C# advice stems from two issues:

  1. The fact that structs are value types and thus have value semantics.
  2. The fact that structs in C# have to deal with autoboxing and must be very worried about the cost of copying.

Structs are also value types in D, but they're powerful enough to be able to have reference semantics if you want to, and the addition of postblit constructors and destructors makes them useful for far more than what you can do with structs in C#. And since D doesn't have autoboxing, the concerns about autoboxing don't apply to D. You still don't want your structs to be huge, since unless you pass by ref, they're going to be copied whenever you pass them to a function, but it's definitely not as large a concern as it is in C#. It's much more in line with C++ in that regard.

And the advice about immutability does not apply at all to D. D structs are frequently mutable, and it would be a big problem if they weren't. Ranges, for instance, are usually implemented as structs, and that wouldn't be possible if you couldn't mutate them.

So, no, I don't think that the C# advice really applies to D. The situation between the two languages is just too different. It would be better to think of D's structs as C++ classes which don't have any base classes and can't be derived from, since that's far closer to what they actually are than C#'s structs.

就是爱搞怪 2024-12-04 14:49:44

结构体是按值传递的,因此大小确实是一个考虑因素(尽管可以使用 refin 来避免这种情况),

大多数情况下,当您只需要按值传递时,您应该使用结构体(对对象的更改不应传播)或者它是一个短暂的对象,其生命周期短到足以保留在堆栈中(就像您将在 std.algorithm 模块中看到的范围对象;所有那里的函数几乎都返回一个结构)

我个人已经为数据对象(单值子句)定义了结构,例如二维点和角度,并为它们定义了一些方便的函数和运算符重载

structs are passed by value so size is indeed a consideration (though one can avoid that with ref and in)

mostly you should use structs when you need to pass by value only (changes to the object shouldn't propagate) or it's a short lived object whose lifespan is short enough to remain on the stack (like a range object as you'll see in the std.algorithm module; all the functions there nearly all return a struct)

personally I've defined structs for data objects (the single value clause) like a 2d point and an angle with some convenience functions and operator overloading defined for them

白芷 2024-12-04 14:49:44

与 C# 中相同的建议通常适用于 D——它们几乎是相同的概念。

唯一的例外是拳击建议——它不适用,因为拳击在 D 中并不真正存在。

The same recommendations generally apply to D as in C# -- they're pretty much the same concepts.

The only exception is the boxing recommendation -- it doesn't apply, since boxing doesn't really exist natively in D.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文