Pourquoi ne pas signaler l'erreur?
Non, c'est le problème; c' est le signalement de l'erreur réelle.
Laissez-moi vous expliquer avec un exemple légèrement plus complexe. Supposons que vous avez ceci:
class CustomerCollection
{
public IEnumerable<R> Select<R>(Func<Customer, R> projection) {...}
}
....
customers.Select( (Customer c)=>c.FristNmae );
OK, qu'est-ce que l'erreur en fonction de la spécification C# ? Vous devez lire la spécification de très prudemment. Nous allons travailler.
Nous avons un appel à Sélectionner comme un appel de fonction avec un argument simple et pas de type d'arguments. Nous faisons une recherche sur Sélectionner dans CustomerCollection, à la recherche de opposables choses nommé Sélectionnez-en fait, des choses comme des champs de type délégué, ou des méthodes. Puisque nous n'avons pas les arguments de type spécifié, nous faisons correspondre sur n'importe quel méthode générique Sélectionner. Nous trouvons l'un et construire une méthode de groupe hors de lui. La méthode de groupe ne contient qu'un seul élément.
La méthode de groupe doivent désormais être analysés par la résolution de surcharge de déterminer d'abord l' ensemble candidat, puis de déterminer l' applicables ensemble candidat, et de déterminer la meilleure candidate, et de déterminer l' a finalement validé la meilleure candidate. Si aucune de ces opérations ne sont pas ensuite de résolution de surcharge doit échouer avec une erreur. Dont l'un d'eux tombe en panne?
Nous commençons par la construction de l'ensemble candidat. Afin d'obtenir un candidat nous devons effectuer la méthode d'inférence de type pour déterminer la valeur de l'argument type R. Comment fonctionne la méthode d'inférence de type de travail?
Nous avons un lambda dont les types de paramètres sont tous connus -- le paramètre formel est Client. Afin de déterminer R, nous devons faire une correspondance entre le type de retour de la lambda à R. Quel est le type de retour de la lambda?
Nous supposons que c est à la Clientèle et de tenter d'analyser le corps de lambda. Faire une recherche de FristNmae dans le contexte de la Clientèle, et la recherche échoue.
Par conséquent, lambda retour de l'inférence de type échoue et aucune limite est ajouté à R.
Après tous les arguments sont analysés, il n'y a pas de limites sur R. la Méthode d'inférence de type est donc impossible de déterminer un type de R.
Par conséquent, la méthode d'inférence de type échoue.
Par conséquent, aucune méthode n'est ajouté à l'ensemble candidat.
Par conséquent, le candidat de l'ensemble est vide.
Par conséquent, il ne peut être applicable candidats.
Par conséquent, le corriger message d'erreur ici serait quelque chose comme "résolution de surcharge n'a pas pu trouver enfin validé la meilleure candidate, car le candidat était vide."
Les clients seraient très malheureux avec ce message d'erreur. Nous avons construit un grand nombre d'heuristiques dans le rapport d'erreur algorith qui tente de déterminer le plus "fondamentaux" de l'erreur que l'utilisateur puisse prendre des mesures concrètes pour corriger l'erreur. Nous avons raison:
OK, devrait nous rendre compte de l'erreur "résolution de surcharge a échoué parce que la méthode d'inférence de type a échoué"? Là encore, les clients serait malheureuse avec qui. Au lieu de cela, nous avons à nouveau poser la question "pourquoi avez-méthode d'inférence de type échec?"
- Parce que l'ensemble relié de R était vide.
C'est une sale erreur de trop. Pourquoi les limites fixées vide?
- Parce que le seul argument à partir de laquelle nous avons pu déterminer R est un lambda dont le type de retour ne peut pas être déduit.
OK, devrait nous rendre compte de l'erreur "résolution de surcharge a échoué car le lambda de retour de l'inférence de type a omis de déduire un type de retour"? De nouveau, les clients serait malheureuse avec qui. Au lieu de nous poser la question "pourquoi le lambda ne parviennent pas à en déduire un type de retour?"
- Parce que le Client ne dispose pas d'un membre nommé FristNmae.
Et c' est l'erreur que nous en fait rapport.
Donc, vous voyez absolument tortueux de la chaîne de raisonnement que nous avons à parcourir afin de donner le message d'erreur que vous le souhaitez. Nous ne pouvons pas dire ce qui n'allait pas -- que la résolution de surcharge a été donné un vide candidat set -- nous devons creuser dans le passé pour déterminer comment la résolution de surcharge suis dans cet état.
Le code qui n'est donc extrêmement complexe; il traite avec des situations plus complexes que celle que j'ai présentée, y compris dans les cas où il y a n différentes méthodes génériques et l'inférence de type échoue pour les m raisons différentes et nous devons travailler à sortir de chez eux tous ce qu'est le "meilleur" de raison de donner à l'utilisateur. Rappelons que dans la réalité il y a une douzaine de différents types de Sélectionner et de résolution de surcharge sur chacun d'entre eux peut échouer pour des raisons différentes ou la même raison.
Il y a des heuristiques dans le rapport d'erreur du compilateur pour faire face à toutes sortes de surcharge de résolution des défaillances; celui que j'ai décrit, c'est juste l'un d'eux.
Alors maintenant, passons à votre cas particulier. Quelle est la véritable erreur?
Nous avons une méthode de groupe avec une seule méthode en elle, Foo. Peut-on construire un ensemble candidat?
Oui. Il y a un candidat. La méthode Foo est un candidat à l'appel, car elle a tout le nécessaire paramètre fourni-bar -- et pas de paramètres supplémentaires.
OK, le candidat a une méthode unique en elle. Est-il un membre de l'ensemble candidat?
Pas de. L'argument correspondant à la barre ne peut pas être convertie dans le type de paramètre formel parce que le corps de lambda contient une erreur.
Donc applicables ensemble candidat est vide, et il n'est donc pas validée définitivement la meilleure candidate, et par conséquent la résolution de surcharge échoue.
Alors, que devez-l'erreur de l'être? Encore une fois, nous ne pouvons pas simplement dire "résolution de surcharge pas réussi à trouver un validée définitivement la meilleure candidat" parce que les clients ne nous haïssent. Nous devons commencer à creuser pour le message d'erreur. Pourquoi la surcharge de la résolution de la panne?
- Parce que l'applicables ensemble candidat était vide.
Pourquoi était-il vide?
- Parce que chaque candidat dans elle a été rejetée.
Y avait-il un meilleur candidat possible?
- Oui, il n'y a qu'un seul candidat.
Pourquoi était-il rejeté?
- Parce que son argument n'a pas été converti vers le type de paramètre formel.
OK, à ce stade, apparemment, l'heuristique qui gère la surcharge de résolution de problèmes qui touchent les arguments nommés décide que nous avons creusé assez loin et que c'est l'erreur que nous devrions rapport. Si nous n'avons pas les arguments nommés à un autre heuristique demande:
Pourquoi l'argument non convertibles?
- Parce que le corps de lambda, contenait une erreur.
Et puis, nous signaler cette erreur.
L'erreur heuristiques ne sont pas parfaits, loin de là. Par coïncidence, je suis cette semaine en faisant une lourde rearchitecture de la "simple" résolution de surcharge de rapport d'erreur heuristiques -- juste des trucs comme quand dire "il n'y avait pas une méthode qui a pris 2 paramètres" et quand à dire "la méthode que vous voulez, c'est privé" et dire "il n'y a pas de paramètre qui correspond à ce nom", et ainsi de suite; c'est tout à fait possible que vous appelez une méthode avec deux arguments, il n'existe pas de méthodes publiques de ce nom avec deux paramètres, il en est un qui est privé, mais l'un d'eux a un nom d'argument qui ne correspond pas. Rapide, quelle erreur devrions-nous le rapport? Nous avons deviner, et parfois, il y a une meilleure proposition que nous aurions faites, mais n'ont pas été suffisamment élaborée pour faire.
Même l'obtention de ce droit se révèle être une très délicat travail. Quand nous avons fini par arriver à recréer l'architecture de la grande lourds heuristiques -- comment faire face à l'échec de la méthode d'inférence de type à l'intérieur des expressions LINQ -- je vais revoir votre cas et voir si nous pouvons améliorer l'heuristique.
Mais depuis le message d'erreur que vous obtenez est complètement correct, ce n'est pas un bug du compilateur; plutôt, il s'agit d'une lacune du rapport d'erreur heuristique dans un cas particulier.