O método MATRICULAR adiciona ao Set e ao Dicionario, já o método SUBSTITUIR só afeta o Dicionário. Acho que gerou uma inconsistência, não?
internal void SubstituirAluno(Aluno aluno)
{
dicionarioAlunos[aluno.NumeroMatricula] = aluno;
}
internal void Matricular(Aluno aluno)
{
alunos.Add(aluno);
dicionarioAlunos.Add(aluno.NumeroMatricula, aluno);
}