No voy a entrar aquí a explicar las diferencias "de bulto" entre clases y estructuras en .NET. Todo programador de la plataforma debería conocerlas pues es lo primero que se aprende.

Sin embargo sí me gustaría resaltar una cuestión simple consecuencia de sus diferencias y que a muchos les puede pasar inadvertida. Se trata del comportamiento obtenido al instanciar una matriz.

Imaginemos que tenemos una sencilla estructura como esta:

struct Usuario
{
   public string Nombre;
   public string Apellidos;
}

Si creamos una matriz de estructuras de este tipo así:

Usuario[] usuarios = new Usuario[10];

podremos inmediatamente asignar valores a cada elemento de la matriz, ya que la estrucutra al ser un tipo por valor está disponible para que la usemos:

usuarios[0].Nombre = "Pepe"; //No fallará

Sin embargo si cambiamos la definición de Usuario conviertiéndola en una clase:

class Usuario
{
   public string Nombre;
   public string Apellidos;
}

El código de asignación anterior fallará debido a que al crear la matriz (el código es exactamente el mismo) no se crean al mismo tiempo nuevos objetos de la clase Usuario, sino que la matriz contiene referencias a objetos de tipo Usuario, pero no objetos de tipo Usuario, cosa que sí pasa al instanciar tipos por valor como las estructuras.

Para hacer la asignación primero habrá que instanciar un objeto y asignarlo al elemento de la matriz:

//Esto fallaría
//usuarios[0].Nombre = "Pepe";

//Esto es lo correcto en este caso
Usuario u = new Usuario();
u.Nombre = "Pepe";
usuarios[0] = u;

//O bien esto otro que es equivalente...
Usuario u = new Usuario();
usuarios[0] = u;
usuarios[0].Nombre = "Pepe";

Esta sutil diferencia hace mucho más fácil crear y usar matrices de estructuras que matrices de clases, aunque claro, no todo son ventajas. Las matrices de estructuras ocupan más memoria y el hecho de utilizarlas después implica realizar más procesos de Boxing/Unboxing que son costosos en términos de rendimiento. Aún así en la mayor parte de las aplicaciones este hecho no nos afectará.
En cada caso hay que sopesar qué es lo mejor pero conviene ser consciente de estas diferencias, que por cierto no existen (en lo que se refiere a la forma de usarlas en código) en la mayor parte de las demás situaciones.

Escrito por un humano, no por una IA