我对struct
类型有所了解。但我无法理解:它是为了什么?我什么时候用它?类,简单的值类型和枚举 - 这就是我所需要的。
有什么建议吗?
UPD:请!不要告诉我结构在堆栈中(我知道这个:)。什么结构用于?答案 0 :(得分:22)
如果需要值类型语义,则选择结构。如果需要引用类型语义,则选择一个类。所有其他问题都是次要问题。
答案 1 :(得分:9)
MSDN提供了指南:Choosing Between Classes and Structures:
如果类型的实例很小并且通常是短暂的或者通常嵌入在其他对象中,请考虑定义结构而不是类。
除非类型具有以下所有特征,否则不要定义结构:
- 它逻辑上表示单个值,类似于基本类型(整数,双精度,>等)。
- 实例大小小于16个字节。
- 这是不可改变的。
- 不必频繁装箱。
答案 2 :(得分:5)
应该是结构的东西(因为它们是值):
struct Color
struct Point
struct Rectangle
struct GLVertex
(包含位置,颜色,法线和texcoord)struct DateTime
应该是一个类的东西(因为它们是你所指的东西):
class RandomGenerator
class Socket
class Thread
class Window
为什么呢? 请考虑以下代码。
class Button
{
public Point Location { get; set; }
}
class Program
{
public static void Main()
{
var button = Util.GetButtonFromSomewhere();
var location = button.Location;
Util.DrawText("one", location);
location.Y += 50;
Util.DrawText("two", location);
location.Y += 50;
Util.DrawText("three", location);
}
}
这将绘制3个垂直对齐的文本标签。但是如果Point是一个类,这也会移动按钮,这是非常意外的:var location = button.Location
感觉它应该复制一个值,而不是一个引用!换句话说,我们将Point视为值类型而不是引用类型。这里的“值”用于值的数学意义上。考虑数字5,它是一个抽象对象“在那里的某个地方”,你只是“引用”它。同样,Point只需即。它不会驻留,我们无法更改它。因此我们选择使它成为一个结构,因此它具有用户期望的语义。
另一方面,我们可以class Button { public Window Parent { get; set; } }
。在此处,Parent
是实体,因此我们使用引用类型Window
来表示它。使用像myButton.Parent.Redraw();
这样的代码可能是有意义的。所以Window
应该是一个类。
到目前为止一切顺利。但这一切对你来说可能听起来太模糊了。你如何真正决定某些东西“感觉”像参考或价值?我的经验法则很简单:
Foo a = b; a.Mutate();
应该做什么?
答案 3 :(得分:4)
简单值类型最好通过struct实现。
结构使用指南
建议您使用 结构符合任何类型的结构 以下标准:
* Act like primitive types. * Have an instance size under 16 bytes. * Are immutable. * Value semantics are desirable.
您还必须了解在堆上分配了一个类实例。 结构 - 是一个vallue类型 - 并在堆栈上分配。
答案 4 :(得分:4)
首先,您必须了解值类型和引用类型之间的区别。我会假设,因为你说跳过那部分,你明白它是什么。
Struct是一种值类型,您将获得使用值类型的所有权限。
结构按值传递。当你做
之类的事情DateTime time = new DateTime(); DateTime newTime = time; //你没有引用时间 //相反,您已经创建了一个新实例
结构不是轻量级类,它们可能有很多方法,只需查看DateTime
结构。
结构可能性能较轻,但并非总是如此。考虑将大型结构传递给方法。因为每次将结构传递给方法时结构都是值类型,所以创建了结构的新实例,因此每次都复制结构。如果你有一个相当大的结构,这将是一个更大的性能命中。
您可能偶尔会使用box和unbox结构,因为它们是值类型。
简而言之,使用结构来表示内存中的原子值。
答案 5 :(得分:3)
当你想要一个带有值(而不是引用)语义的“类”时,你可以使用结构。
答案 6 :(得分:3)
结构体用于表示某些内容的对象,该内容的标识由存储在其属性中的值定义,而不是由Id或键定义。这些称为“值类型”,而不是称为“实体类型”的对象,其身份随着时间的推移而持续存在,并且不依赖于对象属性的值。
作为示例,Person类(实体)具有从一个会话到另一个会话持续存在的身份,即使是年复一年,尽管人的地址,电话号码,雇主等可能会从一个实例发生变化到另一个。如果您无意中同时在内存中有两个Person类实例(代表相同的个体/实体),那么它们的属性具有相同的值非常重要。
CalendarMonth对象otoh(值类型)只有由该值定义的标识,该值指定它是哪个日历月...无论您使用多少个“March 2009”实例,它们都是可互换的equivilent。另一个例子可能是表示税收计划中的财政年度指定的对象。一个很好的例子是地址对象。 (这里不是谈论地址与个人或企业或任何其他实体的关联,而只是地址本身)。更改地址的任何属性使其成为不同的地址。在内存中创建地址对象后,它与每个具有相同属性的其他地址对象是等效的并且可以互换。这就是为什么这些值类型通常应该是不可变的。如果需要,可以使用所需的属性值创建一个新的,并在完成使用后将其丢弃。
答案 7 :(得分:1)
如果你不知道为什么需要它,你可能不会。
struct是值类型而不是引用类型。如果您不知道这意味着什么,那么您可能根本不需要它。
答案 8 :(得分:1)
示例:假设您希望数据类型表示X Y Z处的坐标。您实际上不需要任何功能,只需要三个变量。一个结构对此有好处,一个类可能有点矫枉过正。
答案 9 :(得分:0)
实际上,我认为struct是来自C的遗产。我认为我们必须在任何条件下使用它。也许有时候你觉得把东西放在堆栈而不是堆上更有效率;但是由于Java / C#永远不会像第一站一样高效,所以只是忽略它:)这是我的观点。