Question: I am creating a geometry library in C# and I will need the following *immutable* types:

* `Vector2f` (2 `float`s - 8 bytes)
* `Vector2d` (2 `double`s - 16 bytes)
* `Vector3f` (3 `float`s - 12 bytes)
* `Vector3d` (3 `double`s - 24 bytes)
* `Vector4f` (4 `float`s - 16 bytes)
* `Vector4d` (4 `double`s - 32 bytes)

I am trying to determine whether to make them structs or classes. [MSDN](http://msdn.microsoft.com/en-us/library/ms229017.aspx) suggests only using a struct if the size if going to be no greater than 16 bytes. That reference seems to be from 2005. Is 16 bytes still the max suggested size?

I am sure that using structs for the `float` vectors would be more efficient than using a class, but what should I do about the `double` vectors? Should I make them structs also to be consistent, or should I make them classes?

**Updated:**
Looks like the everyone agrees they should be structs. Thanks for the great answers.

Answer: 
Structs, definitely. Why? Well, it's part feeling I guess, a vector just feels and behaves like a *value*. 

Rico Mariani [here](http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx) gives some reasons why value types were chosen for certain types for an API (I don't think it's XNA he's talking about). 

And while efficiency is a factor here, I don't think it's about garbage collection, but more about *data density* like Rico says. Say you also have a `Vertex` type, that contains two `Vector3`s: a `Vector3` for the normal and a `Vector3` for the world co-ordinates. If you made those types classes, then having an array with 100 `Vertex` elements, would consist of:

* 100 \* 8 bytes (8 bytes is I believe the overhead of a class in memory, 4 bytes for the type header and 4 bytes for something else, a GC handle?)
* 100 \* 4 bytes (for the pointers in the array to the `Vertex` elements)
* 200 \* 4 bytes (for the pointers from each `Vertex` to the two `Vector3` elements)
* 200 \* 8 bytes (for the 8 byte overhead that you pay for making `Vector3` a class)
* 200 \* 12 bytes (for the actual payload of 3 `float` per `Vector3`)

---

6000 bytes (on a 32-bit system).

As a value type, it's simply 200 \* 12 bytes = 2400 bytes. So much more efficient space-wise not to mention a lower level of indirection when reading the array.

But taking up a lot of space doesn't necessarily make it slow, using a value type incorrectly can be slower than making it a class, as [I have found out](https://stackoverflow.com/questions/597259/when-are-structs-the-answer). You definitely want to pass them by `ref` as much as possible, avoid copying them, but this doesn't go for *all* operations, so measure. I think I remember calculating the dot-product was slower when passing by `ref`, perhaps because it somehow prevented in-lining by making the IL larger. But don't take my word for it, just measure.
I assume you're worried about perf?

If they're immutable, they should be behaviorally identical. Just go with one, and if it turns out that there's a perf issue, switch it later on.

If you're targetting .NET CE at all, you should probably consider using structs as the GC isn't as efficient as the full .NET implementation.