2015-07-31 26 views
71

Ho un metodo con le seguenti sovraccarichi:Perché questo cast è ridondante?

string Call(string function, Dictionary<string, object> parameters, object body) 
string Call(string function, Dictionary<string, object> parameters, JObject body) 

Ora ho aggiunto un altro di sovraccarico:

string Call(string function) 
{ 
    return Call(function, null, (JObject) null); 
} 

ho aggiunto un cast al JObject in modo che il compilatore sa che sovraccarico dovrebbe usare. Ma Visual Studio mi dice che il cast è ridondante. Ma perché la mia chiamata non è ambigua senza il cast?

+18

Anche se non è ambiguo per il compilatore, terrei il cast lì come potrebbe essere ambiguo alla persona che legge il codice – Alex

+5

@jean No, non è questo il motivo. Sto dicendo al compilatore quale sovraccarico usare. Inoltre, è importante sapere quale overload di metodo viene utilizzato poiché potrebbero avere implementazioni completamente diverse. 'null' è' null', ma il cast qui è un suggerimento su quale sovraccarico dovrebbe essere usato. – fero

+1

@jean Ho paura che questo sia di nuovo sbagliato. Il cast è ridondante solo perché il compilatore _still_ userà il sovraccarico 'JObject' anche se non scrivo su' JObject' perché usa il sovraccarico più specifico che corrisponde ai parametri, e 'null' può corrispondere a qualsiasi cosa e' JObject' è più specifico di "oggetto". Vedi la risposta di Jon Skeet per una spiegazione dettagliata. – fero

risposta

96

Ma perché la mia chiamata non è ambigua senza il cast?

A causa del sovraccarico con il parametro JObject è "migliore" di sovraccarico con il parametro object ... perché la conversione da null a JObject è "migliore" rispetto alla conversione da null a object.

JObject è più specifico rispetto object, perché c'è una conversione implicita da JObject a object, ma non viceversa.

Se il parametro finale per il primo metodo era string invece (per esempio) allora né sovraccarico sarebbe meglio dell'altro, e la chiamata sarebbe ambigua senza il cast.

Vedere la sezione 7.5.3 della specifica C# 5 per tutti i dettagli complessi. In particolare, la sezione 7.5.3.5 ("migliore obiettivo di conversione") è pertinente qui.

+8

Anche se un cast non è necessario con la classe così com'è oggi, il mancato lancio di 'null' renderà il codice chiamante molto fragile, poiché l'aggiunta di * quasi ogni * ulteriore sovraccarico di tipo di riferimento potrebbe rompere il codice chiamante che non lancia. Non considererei ridondante alcun cast di riferimento nullo nei casi in cui vi sia una possibilità realistica di sovraccarichi di tipo di riferimento aggiuntivi che potrebbero diventare ambigui o anche nei casi in cui un particolare sovraccarico viene considerato "migliore" da le regole, ma è tutt'altro che ovvio che è meglio in ogni senso pratico. – supercat

+1

BTW, ho pensato a lungo che i linguaggi con sovraccarico trarrebbero grandi benefici da un modo di utilizzare attributi o altri mezzi per specificare alcuni sovraccarichi dovrebbero essere considerati "preferiti" se sono utilizzabili, mentre altri dovrebbero essere considerati solo come "fallback" "; Ho anche pensato che sarebbe utile se un sovraccarico potesse specificare un tipo di parametro di 'null'. Conosci qualche lingua che fa cose del genere? – supercat

+0

@supercat: No, non ho paura. –