A resposta de Svick é boa, mas pensei em acrescentar alguns pontos extras.
Primeiro, o parágrafo é falho. Os tipos de ponteiro não herdam do objeto. Os valores em tempo de compilação conhecidos por serem tipos de interface ou tipos de parâmetro de tipo, em tempo de execução, serão referências inválidas ou instâncias de boa-fé de algo que herda do objeto, mas sempre me foi estranho dizer que esses tipos " herdar "do objeto; herança é a propriedade que os membros do ancestral são membros do descendente, mas normalmente você não pensa em "ToString" como membro de IEnumerable. Você pensa nisso como um membro da coisa que implementa IEnumerable .
O parágrafo também é defeituoso porque este é o único local em que "tipo primitivo" aparece na especificação e aparece sem definição. Portanto, é desnecessário e confuso e deve ser removido.
Eu queria que este parágrafo fosse corrigido por um tempo. Da próxima vez que vir Mads, vou lembrá-lo.
Para responder à sua pergunta específica: svick está obviamente correto, mas é útil ver um exemplo específico. Quando voce diz:
struct ColorfulInt
{
int value;
Color color;
...
}
e você cria, digamos, uma matriz:
ColorfulInt[] x = new ColorFulInt[100];
Em seguida, o armazenamento dessas 100 polegadas e 100 cores entra no próprio array . Se ColorfulInt fosse uma classe, a matriz conteria 100 referências a ColorfulInt, cada uma das quais teria que ser alocada individualmente. Alocar individualmente esses cem elementos é muito menos eficiente no tempo e no espaço do que simplesmente alocar o armazenamento diretamente na própria matriz.