Potresti voler vedere come fa Hibernate. Vedi SingleTableEntityPersister se si sta veramente utilizzando l'ereditarietà a tavolo singolo.
O meglio ancora ... basta usare Hibernate / NHibernate o un altro ORM e non reinventare la ruota.
Per essere chiari, non sono un grande fan degli ORM, ma frasi come "ereditarietà a tavolo singolo" implicano che stai già provando a mappare le relazioni oggettuali in modo "manuale" e ti risparmierai un sacco di tempo usando uno strumento che fa tutto il lavoro pesante per te.
Se devi farlo da solo per qualsiasi motivo ... beh, come puoi vedere, ci sono diversi metodi, ma in genere dovrai usare una colonna discriminatore, e per questo dovrai o hanno bisogno di una mappa, di un'istruzione switch o di una convenzione coerente (ad esempio, il valore del discriminatore ha una relazione ovvia con il nome della classe e puoi istanziarlo direttamente con la riflessione). L'istruzione switch diventerà la più veloce ed è probabilmente l'approccio preferito per un numero piuttosto ridotto di classi derivate.
Strumenti come Hibernate non possono farlo in quel modo perché, ovviamente, richiederebbero conoscenze specialistiche sulla gerarchia specifica, che non hanno. Tu fai hai questa conoscenza, così puoi saltare tutta la mappatura / riflessione e usare semplicemente switch / case in una classe di fabbrica da qualche parte. Il fatto che qualcuno possa dimenticare di aggiornarlo in futuro non è davvero un argomento ... la tua fabbrica dovrebbe lanciare un'eccezione non appena incontra un valore discriminatore sconosciuto.
Se sei davvero così preoccupato, fai del discriminatore un enum e scrivi un test unitario per la fabbrica che itera su ogni valore enum noto e prova ad istanziarlo con la fabbrica. In questo modo, il futuro programmatore di manutenzione lo scoprirà immediatamente se gli manca qualcosa.