C#为什么需要struct,如果类可以覆盖它?

时间:2010-02-19 21:13:48

标签: c# struct

只是想知道为什么我们需要struct如果类可以做所有结构可以和更多?我认为在课堂上放置价值类型没有副作用。

编辑:看不出使用struct

的任何强有力的理由

结构类似于类,具有以下主要区别:

  • 结构是一种值类型,而一种是 class是引用类型。
  • 结构不支持继承 (除了含蓄地衍生自 对象)。
  • 结构可以包含所有成员a class可以,但以下情况除外:
  • 无参数构造函数
  • 终结者
  • 虚拟会员

当需要值类型语义时,使用结构而不是类。结构的好例子是数字类型,其中赋值复制值而不是引用更自然。因为struct是值类型,所以每个实例都不需要实例化堆上的对象。在创建类型的许多实例时,这很重要。

9 个答案:

答案 0 :(得分:16)

自定义值类型不是绝对必要的 - 例如,Java没有它们。但是,它们仍然有用。

例如,在Noda Time中,我们非常广泛地使用它们,作为一种有效的方式来表示像瞬间这样的东西,而不会涉及对象的开销。

我不会说“类可以做所有结构可以做更多” - 它们的行为方式不同,应该有不同的想法。

答案 1 :(得分:9)

为什么在struct有效时使用class?因为有时候class不起作用。

除了Reed Copsey提到的性能原因(简短版本:GC需要跟踪的对象越少,允许GC做得更好),有一个地方必须使用:P / Invoke到需要按值结构或结构成员的函数。

例如,假设您要调用CreateProcess()函数。进一步假设您希望将{em> lpStartupInfo 参数的STARTUPINFOEX结构用于CreateProcess()

嗯,STARTUPINFOEX是什么?这样:

typedef struct _STARTUPINFOEX {
    STARTUPINFO                    StartupInfo;
    PPROC_THREAD_ATTRIBUTE_LIST    lpAttributeList;
} STARTUPINFOEX, *LPSTARTUPINFOEX;

请注意STARTUPINFOEX包含STARTUPINFO作为其第一个成员。 STARTUPINFO是一个结构。

由于类是引用类型,因此我们声明了相应的C#类型:

[StructLayout(LayoutKind.Sequential)]
class STARTUPINFO { /* ... */ }

class STARTUPINFOEX { public STARTUPINFO StartupInfo; /* ... */ }

相应的内存中布局错误,因为STARTUPINFOEX.StartupInfo将是指针(ILP32平台上的4个字节),而不是一个结构(如是必需的,在ILP32平台上大小为68字节。)

因此,为了支持调用接受任意结构的任意函数(这是P / Invoke的全部内容),有两件事是必要的:

  1. 完全支持值类型。这允许C#为STARTUPINFO声明一个值类型,它将具有正确的内存布局以进行编组(即struct支持,如C#所示。

  2. P / Invokeable结构中的一些替代语法,它将通知运行时封送程序,该成员应该作为值类型而不是指针布局。

  3. (2)是一个可行的解决方案(并且可能已在Visual J ++中用于J / Direct;我不记得了),但是假设适当的值类型更灵活,则启用许多性能优化,否则无法实现并且在P / Invoke场景中明智地使用,C#支持值类型也就不足为奇了。

答案 2 :(得分:3)

一般情况下,请使用一个类。

只有在绝对需要值类型语义时才使用结构。

答案 3 :(得分:2)

出于性能原因,通常还需要结构。结构数组占用的内存要少得多,并且比对象引用数组获得更好的缓存一致性。如果您正在使用类似渲染系统的东西,并且需要生成500万个顶点,这一点非常重要。

有关详细信息,请参阅Rico Mariani's Performance Quiz + Answers

答案 4 :(得分:2)

结构很有用,因为它们是通过值传递的,这在某些算法中实际上很有用。这实际上是班级不能做的事情。

struct ArrayPointer<T>
{
    public T[] Array;
    public int Offset;
}

您可以将此结构传递给方法,并且该方法可以根据自己的需要更改Offset的值。同时,一旦从方法返回,它将表现为Offset永远不会改变。

答案 5 :(得分:1)

答案 6 :(得分:0)

对于普通的应用程序开发人员来说,使用类是常态。从表面上看,类似的结构似乎是不必要的,但是当你深入研究细节时,它们实际上是完全不同的。

有关结构和类之间的一些差异,请参阅here

最着名的区别是类是引用类型,而结构是值类型。这很重要,因为它允许库开发人员控制如何使用数据类型的实例。

答案 7 :(得分:0)

1,表现。在某些使用结构的情况下,我们会获得更好的性能 2,数据不变性。通过更改结构的某些属性,您将获得一个新结构。这在某些情况下非常有用 3,更好地控制内存表示。我们可以准确地定义结构在内存中的位置,这使我们能够快速有效地序列化和反序列化某些二进制数据。

答案 8 :(得分:0)

使用win32 API使用的底层数据结构几乎是必须的。我认为将它放入.net的一个非常重要的原因可能是由于这个原因。