VB.NET:使用的结构被认为是讨厌的吗?

Ale*_*lex 12 vb.net

我习惯在VB6中使用Structures,并尝试使用.NET来避免它们.只是想知道在2010年使用结构而不是类是否被认为是令人讨厌的?

谢谢您的帮助.

Joh*_*n K 16

选择一个Structure考虑而不是本质上"讨厌".结构可能是令人讨厌的原因; 然而,也有Class可能以自己的方式讨厌的原因......

基本上,当您决定使用这两种面向对象的容器时,您将决定如何使用内存.


有与相关联的不同的语义StructureClass在VB.NET和它们代表不同的存储器使用模式.

通过创建Class您正在创建引用类型.

  • 适合大数据
  • 内存包含对堆上对象位置的引用(如指向对象的概念),虽然对VB.NET程序员透明,因为您处于"托管模式".

通过创建Structure您正在创建值类型.

  • 适合小数据
  • 内存分配包含实际值
  • 要明智,因为它们很容易被推到内存的堆栈区域(即本地变量而不是类字段) - 太大而且你可能遇到堆栈问题.

如果您是音频学习者,还可以在YouTube上观看一些不错的视频资源.

互联网上的许多文章都像这些MSDN文章那样讲授基础知识和细节:


替代文字


Mar*_*tos 6

存在结构是因为在某些情况下它们比类更有意义.它们对于表示小的抽象数据类型特别有用,例如3D点,纬度 - 经度,有理数等.

使用结构的基本动机是避免GC压力.由于结构体是内联的(在堆栈上或在你放入的任何容器内)而不是在堆上,它们通常会导致更少的小分配,如果你需要保存一百万个点或有理数的数组,这会产生巨大的差异.

需要注意的一个关键问题是结构是值类型,因此通常按值传递(明显的例外是ref和out参数).这具有重要意义.例如:

Point3D[] points = ...;
points[9].Move(0, 0, 5);
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常,并将第10点的z坐标增加5.但是,以下代码:

List<Point3D> points = ...;
points[9].Move(0, 0, 5);
Run Code Online (Sandbox Code Playgroud)

仍然会编译并运行,但你会发现第10点的z坐标保持不变.这是因为List的索引运算符返回该点的副本,它是您正在调用的副本Move.

解决方案非常简单.始终通过只读标记所有字段使结构不可变.如果仍需要Move指向,请在Point3D类型上定义+并使用赋值:

points[9] = points[9] + new Point3D(0, 0, 5);
Run Code Online (Sandbox Code Playgroud)