Is there any sense in defining a struct with a reference type member (and not defining it as a class)? For example, to define this struct:
public struct Some
I'm interested to hear what more experienced coders have to say about the pros and cons of this, but my understanding is that, as a value type, a variable of type SomeStruct
would be allocated from the stack, but would contain a reference to the location on the heap containing the string.
In general, a struct should only contain a public and/or mutable field of a reference type if one of the following conditions applies:
If neither condition applies, it may be appropriate for a structure to hold a field of a reference type provided all of the following conditions apply:
In other words, an object reference which is used to encapsulate the state of an object (as opposed to merely identifying it) should only be stored in a struct field if there is no execution path via which the object to which it refers might be modified.
Declaring a field of a reference type means there needs to be space to hold the value of the reference that is pointing to the target object. Thus it makes perfect sense to have such fields in structs.
Nine times out of ten, you should be creating a class rather than a structure in the first place. Structures and classes have very different semantics in C#, compared to what you might find in C++, for example. Most programmers who use a structure should have used a class, making questions like this one quite frankly irrelevant.
Here are some quick rules about when you should choose a structure over a class:
But if you've made an informed decision and are truly confident that you do, in fact, need a structure rather than a class, you need to revisit point number 2 and understand what value type semantics are. Jon Skeet's article here should go a long way towards clarifying the distinction.
Once you've done that, you should understand why defining a reference type inside of a value type (struct) is not a problem. Reference types are like pointers. The field inside of the structure doesn't store the actual type; rather, it stores a pointer (or a reference) to that type. There's nothing contradictory or wrong about declaring a struct with a field containing a reference type. It will neither "slow the object" nor will it "call GC", the two concerns you express in a comment.