Uno dei problemi sarebbe che in molti casi, la chiave per la tabella hash sarebbe una stringa. Quindi i consumatori del metodo dovrebbero sapere in anticipo quali chiavi usare per estrarre i dati. Ciò darebbe la possibilità di errori dovuti a errori ortografici durante l'accesso ai dati.
Un altro inconveniente è la rideterminabilità. Se in seguito deciderai di cambiare il nome di un membro, avrai un sacco di stringhe magiche che devono anche cambiare. È molto più semplice rinominare un membro della classe usando gli strumenti di refactoring forniti dagli IDE più buoni. Con una tabella hash probabilmente dovresti eseguire un'operazione di ricerca / sostituzione su tutti i file di origine che potrebbe essere problematico.
Infine, perderai il controllo del tempo di compilazione dell'accesso membro, sia in termini di nome che di tipo. Quest'ultimo non è un problema se la tua tabella hash contiene solo un tipo di oggetto, ma se contiene molti (anche nella stessa catena gerarchica) vuoi veramente sfruttare il sistema di tipi della tua lingua e ottenere il tempo di compilazione per controllarlo. Nella maggior parte degli IDE avrai un qualche tipo di funzionalità di intelligenza / completamento automatico: questi funzionano guardando il sistema dei tipi, ma non saranno in grado di aiutarti con i tasti tabella hash.
Come per le volte in cui sarebbe appropriato per restituire una tabella hash (o un'altra raccolta di coppie di valori chiave), la userai quando entrambi i valori e le chiavi non sono noti al momento della compilazione. Ad esempio, se hai un metodo che analizza una stringa di query e restituisce le chiavi & valori corrispondenti, una tabella hash sarebbe una buona scelta. In questo caso vorresti anche pensare di restituire una sorta di tabella di hash immutabile o di sola lettura.
Modifica - La maggior parte dei punti sollevati in questa risposta cessano di essere applicati quando parli di lingue dinamiche:)