Che cosa significa "sicuro per i tipi"?
Che cosa significa "sicuro per i tipi"?
Risposte:
Sicurezza dei tipi significa che il compilatore convaliderà i tipi durante la compilazione e genererà un errore se si tenta di assegnare il tipo errato a una variabile.
Alcuni semplici esempi:
// Fails, Trying to put an integer in a string
String one = 1;
// Also fails.
int foo = "bar";
Questo vale anche per gli argomenti del metodo, poiché si stanno trasmettendo loro tipi espliciti:
int AddTwoNumbers(int a, int b)
{
return a + b;
}
Se provassi a chiamarlo usando:
int Sum = AddTwoNumbers(5, "5");
Il compilatore genererebbe un errore, perché sto passando una stringa ("5") e si aspetta un numero intero.
In un linguaggio vagamente digitato, come javascript, posso fare quanto segue:
function AddTwoNumbers(a, b)
{
return a + b;
}
se lo chiamo così:
Sum = AddTwoNumbers(5, "5");
Javascript converte automaticamente il 5 in una stringa e restituisce "55". Ciò è dovuto al javascript che utilizza il segno + per la concatenazione di stringhe. Per renderlo consapevole del tipo, dovresti fare qualcosa del tipo:
function AddTwoNumbers(a, b)
{
return Number(a) + Number(b);
}
O forse:
function AddOnlyTwoNumbers(a, b)
{
if (isNaN(a) || isNaN(b))
return false;
return Number(a) + Number(b);
}
se lo chiamo così:
Sum = AddTwoNumbers(5, " dogs");
Javascript converte automaticamente i 5 in una stringa e li aggiunge per restituire "5 cani".
Non tutti i linguaggi dinamici perdonano come javascript (in effetti un linguaggio dinamico non implica implicitamente un linguaggio tipizzato libero (vedi Python)), alcuni di essi ti daranno effettivamente un errore di runtime su cast di tipi non validi.
Sebbene sia conveniente, ti apre a molti errori che possono essere facilmente persi e identificati solo testando il programma in esecuzione. Personalmente, preferisco che il mio compilatore mi dica se ho fatto quell'errore.
Ora, torniamo a C # ...
C # supporta una funzionalità linguistica chiamata covarianza , ciò significa sostanzialmente che è possibile sostituire un tipo base con un tipo figlio e non causare un errore, ad esempio:
public class Foo : Bar
{
}
Qui, ho creato una nuova classe (Foo) che subclasse Bar. Ora posso creare un metodo:
void DoSomething(Bar myBar)
E chiamalo usando un Foo o una barra come argomento, entrambi funzioneranno senza causare un errore. Questo funziona perché C # sa che qualsiasi classe figlio di Bar implementerà l'interfaccia di Bar.
Tuttavia, non puoi fare l'inverso:
void DoSomething(Foo myFoo)
In questa situazione, non posso passare Bar a questo metodo, perché il compilatore non sa che Bar implementa l'interfaccia di Foo. Questo perché una classe figlio può (e di solito sarà) molto diversa dalla classe genitore.
Certo, ora sono andato ben oltre il limite e oltre lo scopo della domanda originale, ma è tutto buono da sapere :)