只是想知道为什么我们需要struct如果类可以做所有结构可以和更多?我认为,在类中放置值类型没有副作用.
编辑:看不到使用struct的任何强有力的理由
结构类似于类,具有以下主要区别:
当需要值类型语义时,使用结构而不是类.结构的好例子是数字类型,其中赋值复制值而不是引用更自然.因为struct是值类型,所以每个实例都不需要实例化堆上的对象.在创建类型的许多实例时,这很重要.
Jon*_*eet 16
自定义值类型不是绝对必要的 - 例如,Java没有它们.但是,它们仍然有用.
例如,在Noda Time中,我们非常广泛地使用它们,作为一种有效的方式来表示像瞬间这样的东西,而不会涉及到对象的开销.
我不会说"类可以做所有结构可以做更多" - 它们的行为不同,应该有不同的想法.
为什么使用struct一个class有效的?因为有时一个class不起作用.
除了Reed Copsey提到的性能原因(简短版本:GC需要跟踪的对象越少,允许GC做得更好),还有一个地方必须使用结构:P /调用需要的函数按价值结构或结构成员.
例如,假设您要调用CreateProcess()函数.进一步假设您想为lpStartupInfo参数使用STARTUPINFOEX结构.CreateProcess()
那是什么STARTUPINFOEX?这个:
typedef struct _STARTUPINFOEX {
STARTUPINFO StartupInfo;
PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEX, *LPSTARTUPINFOEX;
Run Code Online (Sandbox Code Playgroud)
请注意,STARTUPINFOEX其中包含STARTUPINFO作为其第一个成员. STARTUPINFO是一个结构.
由于类是引用类型,如果我们声明相应的C#类型:
[StructLayout(LayoutKind.Sequential)]
class STARTUPINFO { /* ... */ }
class STARTUPINFOEX { public STARTUPINFO StartupInfo; /* ... */ }
Run Code Online (Sandbox Code Playgroud)
相应的内存中布局是错误的,因为它STARTUPINFOEX.StartupInfo是一个指针(ILP32平台上的4个字节),而不是一个结构(如果需要,ILP32平台上的大小为68字节).
因此,为了支持调用接受任意结构的任意函数(这是P/Invoke的全部内容),需要做以下两件事之一:
完全支持值类型.这允许C#声明一个值类型STARTUPINFO,它将具有正确的内存布局以进行编组(即struct支持,如C#所示).
P/Invokeable结构中的一些替代语法,它将通知运行时封送程序,该成员应该作为值类型而不是指针布局.
(2)是一个可行的解决方案(可能已在Visual J ++中用于J/Direct;我不记得了),但鉴于正确的值类型更灵活,启用许多性能优化,否则无法实现,并使在P/Invoke场景中合理使用,C#支持值类型也就不足为奇了.