29 votes

Vous ne savez pas pourquoi ce code C # se compile, alors qu'un code similaire ne le fait pas

Prenons l'extension suivante de la méthode:

static class Extensions
{
   public static bool In<T>(this T t, params T[] values)
   {
      return false;
   }
}

Je suis curieux de savoir pourquoi ce code compile et s'exécute:

var x = new Object();
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);

Au sein d' In, values est Object[], comme si l' List<int> est converti à la volée à un tableau. Pour moi, il semble qu' params T[] ne correspond pas à IEnumerable<int>, c'est pourquoi je suis surpris de ce court même.

Maintenant ce code:

var x = 5;
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);

Ne pas exécuter et de générer l'erreur de compilateur:

Erreur 2 Argument 2: impossible de convertir de 'Système.Les Collections.Génériques.IEnumerable' int[]'

C'est ce que je m'attendrais à partir de la première en fait. Quelqu'un peut m'expliquer ce qu'il se passe ici? Merci!

41voto

SLaks Points 391154

L'inférence de Type convertit votre premier appel

In<object>(x, p);

Les paramètres de ce fermé méthode générique sont object, params object[].
Donc, en passant p implicitement le convertit en object, qui devient le seul élément dans le tableau params.

Votre deuxième appel est déduite (à cause du premier paramètre) pour

In<int>(x, p);

Ici, le second paramètre peut être soit une int[] (passage d'un tableau directement) ou une série d' ints (via params).
Depuis IEnumerable<int> n'est ni de ceux-ci, vous obtenez un message d'erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X