C#struct将object作为数据成员

Sou*_*rgy 5 c# struct thread-safety

我们知道,在C#中,结构是按值传递的,而不是通过引用传递的.所以,如果我有一个包含以下数据成员的结构:

private struct MessageBox
{
    // data members
    private DateTime dm_DateTimeStamp; // a struct type
    private TimeSpan dm_TimeSpanInterval; // also a struct
    private ulong dm_MessageID; // System.Int64 type, struct
    private String dm_strMessage; // an object (hence a reference is stored here)
    // more methods, properties, etc ...
}
Run Code Online (Sandbox Code Playgroud)

因此,当MessageBox作为参数传递时,堆栈上会产生COPY,对吗?这对数据成员的复制方式意味着什么?前两个是结构类型,因此副本应该由DateTime和TimeSpan组成.第三种类型是基元,因此它也被复制.但是dm_strMessage呢,它是对象的引用?当它被复制时,会创建对同一个String的另一个引用,对吧?对象本身驻留在堆中,并且不被复制(堆上只有一个实例.)所以现在我们必须引用String类型的同一对象.如果从不同的线程访问这两个引用,则可以想象String对象可能会被同时从两个不同的方向修改而被破坏.MSDN文档说System.String是线程安全的.这是否意味着String类有一个内置机制来防止对象在这里描述的情况类型中被破坏?我试图弄清楚我的MessageBox结构是否有任何潜在的缺陷/缺陷是结构与类.感谢您的任何意见.

Source.Energy.

Mar*_*ers 4

字符串不会被多线程访问“损坏”,因为它们是不可变的。

不过,您应该避免使结构可变。阅读此问题和答案以获取更多信息。

我试图弄清楚我的 MessageBox 结构作为结构与类是否有任何潜在的缺陷/陷阱。

它可能不应该是一个结构。请参阅 MSDN 上关于在类和结构之间进行选择的指南。

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

  • 它在逻辑上表示单个值,类似于基本类型(整数、双精度等)。
  • 它的实例大小小于 16 字节。
  • 它是不可改变的。
  • 它不必经常装箱。

我认为您的 MessageBox 肯定违反了第一条和第二条准则,也可能违反了第三条准则,具体取决于可用的方法。