En C # si je veux diviser un string
par un autre, string
je dois faire quelque chose comme ça:
testString.Split(new string[] { "anotherString" }, StringSplitOptions.None);
De la String.Split
documentation MSDN surchargée, nous pouvons voir la mise en œuvre et pourquoi un tel appel doit être effectué.
Venant de Python , il m'est difficile de comprendre correctement pourquoi un tel appel est nécessaire. Je veux dire que je pourrais utiliser Regex.Split
pour obtenir une syntaxe similaire à celle de l'implémentation de Python, mais je devrais le faire au prix de moins de performances (temps de configuration) pour quelque chose de simple .
Donc, fondamentalement, ma question est pourquoi diable ne pouvons-nous pas simplement faire:
testString.Split("anotherString");
Notez que je ne suggère aucun prototype ni implémentation. Je comprends pourquoi vous n'avez pas pu implémenter la version ci-dessus compte tenu de l'API actuelle. Mon objectif était de comprendre pourquoi une telle API aurait pu être créée compte tenu de l'avantage que la syntaxe ci-dessus apporte. À l'heure actuelle, la flexibilité semble être l'objectif du courant String.Split
qui a du sens, mais pour être honnête, je pensais vraiment qu'il y avait une sorte de gain de performances quelque part. Je suppose que j'avais tort.
la source
testString.Split(",.;");
ettestString.Split(new Char [] {',', '.', ';',);
qui ne sont pas la même chose.IEnumerable<char>
afin que le prototype supplémentaire que vous proposez puisse apparaître ambigu dans certains cas (délimitez-vous par la chaîne entière ou par chacun de ses caractères?) Juste une supposition.testString.Split("anotherString");
, je suis assez confiant pour dire que le comportement attendu était de délimiter sur toute la chaîne (anotherString
dans ce cas).Réponses:
Parfois, le fractionnement sur plusieurs caractères / chaînes est utile, de sorte que l'API vous permet de fournir un tableau, vous offrant ainsi une flexibilité maximale. Dans le cas de
char
s, vous obtenez à la fois la simplicité de la syntaxe et la flexibilité puisque le paramètre est marqué commeparams
si vous pouvez écrireSplit('x')
plutôt queSplit(new[]{'x'})
.Alors pourquoi n'y a-t-il pas une option similaire pour les chaînes, vous permettant d'écrire
Split("x")
?C'est peut-être une conséquence malheureuse de la façon dont l'API est conçue. Initialement, cela ne permettait que le fractionnement des caractères. Le fractionnement sur les chaînes a été ajouté en 2.0, probablement parce qu'il est plus complexe à implémenter. Mais il n'était pas possible d'ajouter
String.Split(string)
ou deString.Split(string[])
surcharger, car cela rendrait l'expressiontestString.Split(null)
ambiguë et ce code ne compilerait plus.testString.Split(null)
est en fait un idiome assez courant car il fractionne la chaîne sur les espaces, donc une telle rupture serait trop répandue pour être acceptable.L'utilisation d'un
null
paramètre comme commutateur pour un comportement spécial est généralement considérée comme une mauvaise conception de nos jours, donc je pense qu'il est juste de dire que cette API est juste imparfaite.Il n'y en a pas non
Split(string[], Int32)
plus, probablement pour une raison similaire - ce serait ambiguSplit(char[], Int32)
si le premier paramètre l'estnull
. Il y a des surcharges similaires avec lesStringSplitOptions
paramètres, mais ils ont tous été ajoutés en même temps dans 2.0, donc aucune ambiguïté n'a été introduite dans le code existant.Remarque
Pour être clair, ceci est juste mon hypothèse, je ne connais pas la pensée réelle des concepteurs de framework .net.
la source
Split(null)
ne sert à rien si vous le permettezSplit("")
. Outre le fait qu'elle permettrait une bien meilleure syntaxe, cette dernière est quand même plus verbeuse ...String.Split(null)
ne serait plus ambiguë, afin qu'ils puissent ajouter la surchargeN'étant pas l'auteur des méthodes, je ne sais pas pourquoi cet ensemble de surcharges a été choisi. Cependant, il y a deux choses à noter ici:
Si vous divisez un seul caractère, la
public string[] Split(params char[] separator
version) peut être utilisée ainsi:comme
char[]
est unparams
paramètre.Vous pouvez facilement ajouter votre propre méthode d'extension ici pour obtenir ce que vous voulez:
et
testString.Split("anotherString");
va maintenant travailler pour vous.la source
String
classe, les deux seraient possibles. Ai-je tort ?Différentes langues ont des règles quelque peu différentes pour les conversions implicites et la surcharge, et le .NET Framework est conçu pour être utilisable avec n'importe lequel d'entre eux. Dans le
Option Strict Off
dialecte de VB.NET, une valeur de typeString
peut être transmise à une fonction qui attend unChar[]
comportement équivalent à l'appelToCharArray()
à la chaîne.Je pense que la chose raisonnable à faire aurait été d'avoir des noms séparés pour
Split
(qui accepte un seulChar
ouString
) etSplitMulti
(qui accepterait unChar[]
ouString[]
), mais .NET semble parfois favoriser l'utilisation de la surcharge seule pour choisir différents types d'opérations. Malheureusement, je ne connais aucun moyen d'utiliserString.Split
pour s'adapter à des scénarios d'utilisation qui nécessiteraient de distinguer différents types de délimiteurs autrement qu'en les séparant séparément.Une autre omission est une option pour conserver les délimiteurs, soit en les incluant à la fin de la chaîne précédente, soit au début de la chaîne suivante, ou en ayant des éléments de tableau impairs comme délimiteurs tandis que les éléments pairs sont les choses entre eux.
la source