Nelle istruzioni switch, sono praticamente indispensabili - beh, puoi usare il metodo / classe extract per scomporlo in casi a riga singola, ma ... - Non penso che sia ciò che il tuo professore intende dire .
Per interrompere da un loop è considerato da alcuni un goto con un altro nome. Quindi sta tornando dal centro di un metodo. Ho persino visto un caso simile usato contro le eccezioni. Se ci pensi, ha senso logico; tutti i motivi per evitare l'uso di goto si applicherebbero in modo uguale a più punti di uscita da un ciclo o da un metodo.
Tutti questi costrutti creano percorsi attraverso il codice che non sono lineari.
Ma tutto ciò detto, direi che ognuno di essi rappresenta un luogo in cui goto potrebbe essere usato per migliorare la leggibilità (di solito diminuendo il rientro), quindi avere costrutti linguistici che li rappresentino in modi diversi può essere solo una buona cosa. In questo modo, sappiamo, quando vediamo uno di questi costrutti, che cosa intende fare il codice e possiamo continuare a imporre un criterio di non utilizzo di goto.
Questa è, comunque, la mia opinione. Non credo che tutti siano d'accordo con me. E sarò d'accordo con chiunque sostenga che quando si arriva a scrivere un'interruzione, o un ritorno a metà del metodo, o un'eccezione che copre tutto tranne una situazione inaspettata, si dovrebbe probabilmente pensare a modi migliori per codificarlo. Ricorda, una cosa del genere non esiste sempre.