2
votes

Case-Insensitive List.Contains (): Aucune surcharge pour la méthode 'Contains' prend 2 arguments

C # Case-Insensitive List.Contains (): Aucune surcharge pour la méthode 'Contains' prend 2 arguments

Vous avez une erreur de compilation si nous le faisons

List<string> list = new List<string>();
list.Add("one");
list.Add("two");

string stringToSearch = "OnE";
dynamic stringToSearchDynamic = "OnE";

//compiles OK
bool isContained = list.Contains(stringToSearch, StringComparer.OrdinalIgnoreCase);


//Does NOT compile
isContained = list.Contains(stringToSearchDynamic.ToString(), StringComparer.OrdinalIgnoreCase);

Mais compile OK si nous mettons la chaîne actuelle

list.Contains(stringToSearch, StringComparer.OrdinalIgnoreCase)

S'agit-il d'un bogue du compilateur?

Code:

list.Contains(stringToSearchDynamic.ToString(), StringComparer.OrdinalIgnoreCase)

p >

c#

5 commentaires

Réponse: stackoverflow.com/a/41415574/2794280


Tout d'abord, il n'est pas nécessaire d'utiliser ToString () avec une chaîne . C'est essentiellement un no-op qui renvoie la chaîne elle-même. Si la chaîne est passée comme objet, un simple cast suffit


C'était juste pour le rendre plus clair


@LydonCh un casting est toujours plus clair. Dans ce cas, cela éviterait complètement le problème


@PanagiotisKanavos vous avez raison, un cast fonctionne aussi, car il indique au compilateur de quel type il s'agit. donc cela a fonctionné si je fais list.Contains ((stringToSearchDynamic as string), StringComparer.OrdinalIgnoreCase)


3 Réponses :


6
votes

Le type d'une expression dynamique est également dynamique. Puisque vous avez une variable dynamique, le type de variable.ToString est résolu au moment de l'exécution, pas au moment de la compilation. Il est donc traité comme dynamique et le compilateur ne trouve pas de méthode Contains qui prend dynamic comme premier argument.

Vous pouvez effectuer un cast en chaîne comme suggéré dans les commentaires, cela fonctionne parce que le cast est une chose à la compilation et oblige le compilateur à traiter votre variable comme une chaîne.


3 commentaires

@PanagiotisKanavos se soucie d'élaborer pourquoi?


Le texte d'erreur lui-même se plaint de Contains avec deux arguments, pas d'une incompatibilité de type. Maintenant que j'y pense, List.Contains () n'utilise qu'un un argument. L'OP essaie d'utiliser Enumerable.Contains mais le compilateur essaie d'utiliser List.Contains à la place


si vous essayez avec un int, vous obtenez toujours le même message d'erreur: list.Contains (2, StringComparer.OrdinalIgnoreCase); le compilateur recherche d'abord les méthodes d'instance, puis les méthodes d'extension, mais comme il n'y a pas de méthode qui prend dynamique comme premier argument, il génère cette erreur.



3
votes

Utilisez un cast simple au lieu de ToString () . ToString () est essentiellement un no-op lorsqu'il est appliqué aux instances de chaîne de toute façon, il renvoie simplement la chaîne elle-même. Ceci compile:

isContained = list.Contains((string)stringToSearchDynamic, StringComparer.OrdinalIgnoreCase);

Explication

Le code d'origine essaie d'utiliser le Enumerable.Contains méthode d'extension qui accepte un comparateur comme deuxième argument . La signature de la méthode est Contains (IEnumerable , TSource, IEqualityComparer ) . Cela signifie que la valeur à rechercher elle-même doit être TSource. Dans ce cas cependant, il est dynamique et inconnu jusqu'à l'exécution.

Le compilateur n'essaiera même pas d'utiliser la méthode d'extension et essaiera de trouver lui-même un Contains on List. Ce qu'il trouve cependant est un List.Contains (T) qui n'accepte qu'un paramètre unique et se plaint de plusieurs arguments


0 commentaires

0
votes

J'utilisais .NetFrameWork 4.7.2 et cela fonctionnait bien, mais pour certaines raisons, j'ai dû utiliser .NetFrameWork 2.0 et ici, cela donnait une erreur similaire. donc si vous pouvez utiliser la dernière version du framework, cela peut vous aider.


0 commentaires