Matthew Scharley
Matthew Scharley

Reputation: 132384

Immutable class vs Immutable struct

I have a class that started life being mutable, but I've since made it immutable. Should I change it to be a struct? What sort of considerations go into choosing one over the other? My particular case is a Point type class (it represents a coordinate in a custom coordinate system) that is made up of 4 int fields, plus a few properties to access the same data in different ways. I note that String is a class and is immutable, so there must be some use-case for this.

Upvotes: 10

Views: 1698

Answers (7)

supercat
supercat

Reputation: 81217

The semantics of immutable structs and sealed immutable class-type objects are nearly identical. The performance of structs 16 bytes and smaller will generally be better than the performance of otherwise-identical class-type objects, except when such structs are typecast to Object or an interface type; such typecasts will greatly degrade the performance of structs, but not particularly affect the performance of class types. Note that there is a huge difference between:

  void doSomethingWithIFoo(IFoo whatever);

and

  void doSomethingWithIFoo<T>(T whatever) where T:IFoo;

Passing a struct to the former will require that the struct be typecast to an interface type, while the second form will allow the struct to be handled as its own type.

Upvotes: 0

BrandonAGr
BrandonAGr

Reputation: 6017

If it is small and immutable then making it a struct would be preferable. Especially if you are going to have large collections of lots of Points. If you have a list of 1 million Points, then there will be lots of overhead for all those objects, in terms of both GC time and the 16 bytes of additional overhead per object instance.

String has to be a reference type because you cant and wouldn't want to store a variable number of characters on a stack, not to mention the ability to intern strings and share instances. This msdn article has information on why Tuple was made a reference type.

Upvotes: 2

Kit
Kit

Reputation: 21729

Keep it as a class unless it is small enough that struct makes sense. This will be rare. My thought is that generally speaking the cases for "structness" are rapidly diminishing. If stronger semantics were baked in at the beginnings of the language (immutability and domain value object features) I'd change my mind. As a fairly new example, consider System.Tuple<>. That said, I'd hedge slightly by asking, just what your object is (rhetorically speaking).

Upvotes: 1

Paul Bellora
Paul Bellora

Reputation: 55223

As I understand, using a struct instead of a class is a matter of optimization. Structs are stored on the stack rather than the heap, so they are well suited as lightweight bundles of multiple fields that are used in great quantity. They are copied whenever passed between methods, which makes passing them more expensive - however this may lend itself to your desire for immutability. Disadvantages of using structs include the natural restrictions imposed by the language.

I'm not at all an expert on the subject but wanted to bring this aspect up. Someone with more experience should certainly step in and expand on this. Also, here is a useful discussion on it: When to use struct?

Ultimately I would say if immutability is your only consideration, keep it a class (especially now that I see others voicing this opinion). Immutability can be achieved regardless of being a struct, so the matter doesn't seem strongly related.

Upvotes: 4

Adam Jones
Adam Jones

Reputation: 721

I wouldn't change to a struct for immutability. The biggest difference between a struct and a class is that a struct is a value type and a class is reference type. Structs are copied when passed to a method, but classes passed to a method will be passed by reference. Classes can be immutable just as well as stucts.

Upvotes: 0

Guffa
Guffa

Reputation: 700572

Generally, no, you should not change it to a struct. Just because it's immutable doesn't mean that it's automatically a good candidate for being a struct.

A struct should be small. With your four ints it's just at the recommended limit of 16 bytes where performance for structs starts to degrade.

A struct should represent a single entity of some kind. Perhaps your class does that, but from your description it doesn't sound likely.

A structure is harder to implement correctly than a class. It should behave well to things like comparisons, so there are more things to implement than what is expected of a class.

Unless you have a really good reason to implement it as a struct, like performance issues, you should keep your class as a class.

Upvotes: 6

Jesus Ramos
Jesus Ramos

Reputation: 23266

It really depends on what you want/need to represent the data contained within it. Structs are usually for simple representation or using to to hold multiple values that you may need over and over and classes should be used when the object itself has some required behavior that it needs to accomplish. In your case for the sake of simplicity and allowing you to keep your properties you might as well make this a class.

Immutability is used in some scenarios. For instance if you want something to be a completely new object every time it's changed then you may want to consider immutability (data constraints and such). If you want to be able to pass a class around with very specific information that you do not want changed (maybe some DTO objects from a database that are only created and then passed around with no changes) so that you do not get odd behavior if someone changes a value.

Upvotes: 0

Related Questions