Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# struct with object as data member

As we know, in C# structs are passed by value, not by reference. So if I have a struct with the following data members:

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 ...
}

So when a MessageBox is passed as a parameter, a COPY is made on the stack, right? What does that mean in terms of how the data members are copied? The first two are struct types, so copies should be made of DateTime and TimeSpan. The third type is a primitive, so it's also copied. But what about the dm_strMessage, which is a reference to an object? When it's copied, another reference to the same String is created, right? The object itself resides in the heap, and is NOT copied (there is only one instance of it on the heap.) So now we have to references to the same object of type String. If the two references are accessed from different threads, it's conceivable that the String object could be corrupted by being modified from two different directions simultaneously. The MSDN documentation says that System.String is thread safe. Does that mean that the String class has a built-in mechanism to prevent an object being corrupted in exactly the type of situation described here? I'm trying to figure out if my MessageBox struct has any potential flaws / pitfalls being a structure vs. a class. Thanks for any input.

Source.Energy.

like image 558
Source.Energy Avatar asked May 02 '10 06:05

Source.Energy


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


2 Answers

Strings cannot be "corrupted" by multithreaded access because they are immutable.

You should avoid making your structs mutable though. Read this question and answers for more information.

I'm trying to figure out if my MessageBox struct has any potential flaws / pitfalls being a structure vs. a class.

It probably should not be a struct. See the guidelines on MSDN for choosing between a class and a struct.

Do not define a structure unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).
  • It has an instance size smaller than 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

I think your MessageBox definitely breaks the first and second guidelines, and possibly also the third depending on what methods are available.

like image 118
Mark Byers Avatar answered Oct 29 '22 17:10

Mark Byers


Firstly, your first sentence implies that you think classes are passed by reference. This isn't the case - the reference is passed by value (by default). See my article on parameter passing for more details. When you understand this, it may make other aspects clearer.

Your question is really about two different things:

  • How struct values are copied
  • How safe it is to share strings between threads

I think it will help you if you separate the two.

When copying the value of a struct, the members are treated the same way whether they're value types or reference types. The value is simply copied, bit for bit. The important thing to understand is that the value of dm_strMessage is a reference, not a string object. That reference is copied.

This is no more harmful than this code:

string message = GetMessageFromSomewhere();
string otherMessage = message;

Exactly the same thing happens: the value of message is copied into otherMessage: the two variables have the same value, which is a reference to a single string object.

So far, this has nothing to do with threading. Now if you share a string reference between multiple threads, that's safe - because strings are immutable. You can't change the contents of a string object, so two strings can perfectly happily read data from the same object with no risks of corruption. The same is not true of many other types in .NET. For example, it's not safe to share a List<T> between multiple threads which are potentially going to modify the list.

like image 29
Jon Skeet Avatar answered Oct 29 '22 17:10

Jon Skeet