Comment ssortingng.Format gère-t-il les valeurs NULL?

Dans le code suivant ci-dessous, pourquoi les appels à deux ssortingng.Format ne se comportent pas de la même façon? Dans le premier cas, aucune exception n’est levée, mais dans le second cas, une exception ArgumentNullException est lancée.

 static void Main(ssortingng[] args) { Exception e = null; ssortingng msgOne = ssortingng.Format("An exception occurred: {0}", e); ssortingng msgTwo = ssortingng.Format("Another exception occurred: {0}", null); } 

Quelqu’un pourrait-il m’aider à comprendre la différence entre les deux?

Je devine ici, mais il semble que ce soit la différence de votre appel surchargé. Ssortingng.Format a plusieurs surcharges, c’est à peu près ce que vous frappez.

Dans le premier exemple, il serait logique que vous Ssortingng.Format(ssortingng,object) .

Dans le second exemple, en fournissant null vous Ssortingng.Format(ssortingng,params object[]) probablement Ssortingng.Format(ssortingng,params object[]) qui, selon la documentation, Ssortingng.Format(ssortingng,params object[]) ArgumentNullException lorsque:

format ou args est null.

Si vous exécutez .NET4, essayez d’utiliser les parameters nommés:

 Ssortingng.Format("Another exception occured: {0}", arg0: null); 

Pourquoi frappe-t-il la surcharge de l’ params object[] ? Probablement parce que null n’est pas un object, et la manière dont params fonctionne est que vous pouvez transmettre chaque valeur en tant que nouvel object dans l’appel ou lui transmettre un tableau des valeurs. C’est-à-dire que ce qui suit est un dans le même :

 Ssortingng.Format("Hello, {0}! Today is {1}.", "World", "Sunny"); Ssortingng.Format("Hello, {0}! Today is {1}.", new Object[]{ "World", "Sunny" }) 

Donc, cela traduit l’appel de votre déclaration à quelque chose du genre:

 Ssortingng format = "Another exception occured: {0}"; Object[] args = null; Ssortingng.Format(format, args); // throw new ArgumentNullException(); 

Dans votre premier exemple, vous frappez Format(Ssortingng, Object) , qui ressemble à ceci lors du déassembly:

  public static ssortingng Format(ssortingng format, object arg0) { return Format(null, format, new object[] { arg0 }); } 

Notez le new object[] autour de cela.

Le second, vous frappez apparemment l’utilisation du Format(ssortingng, object[]) , du moins c’est celui qui est invoqué lorsque j’effectue le même test. Démonté, ça ressemble à ça:

  public static ssortingng Format(ssortingng format, params object[] args) { return Format(null, format, args); } 

Tous ces éléments sont donc canalisés vers Format(IFormatProvider, ssortingng, object[]) . Cool, regardons les premières lignes:

 public static ssortingng Format(IFormatProvider provider, ssortingng format, params object[] args) { if ((format == null) || (args == null)) { throw new ArgumentNullException((format == null) ? "format" : "args"); } ... } 

… welp, il y a votre problème, juste là! La première invocation l’enveloppe dans un nouveau tableau, elle n’est donc pas nulle. Passer null explicitement ne le fait pas, à cause de l’instance spécifique de Format() qui appelle.

Le premier appel est résolu comme un appel à Format (object), tandis que le second est résolu comme un appel à Format (object []). Les parameters NULL sont traités différemment par ces différentes surcharges.

La résolution de surcharge est décrite ici . La partie pertinente est que pour le deuxième appel à Format, une surcharge de Format (params object []) est étendue à Format (object []), ce qui est préférable à Format (object). Le littéral null est à la fois un object [] et un object, mais object [] est plus spécifique, donc il est choisi.

Il y a deux différences qui suivent:

  1. Ici, la valeur Null est assignée.

     Exception e = null; ssortingng msgOne = ssortingng.Format("An exception occurred: {0}", e); 
  2. Ici, la valeur NULL ne peut pas être lue dans un format de chaîne, ce qui signifie une erreur de transtypage.

     ssortingng msgTwo = ssortingng.Format("Another exception occurred: {0}", null); 

Je vous donne un exemple simple: Ici, vous ne pouvez pas lire la valeur NULL comme un format de chaîne.

 ssortingng str = null.toSsortingng();