W C #, jeśli chcę podzielić jeden string
przez inny, string
muszę zrobić coś takiego:
testString.Split(new string[] { "anotherString" }, StringSplitOptions.None);
Z przeciążonej String.Split
Dokumentacji MSDN możemy zobaczyć implementację i dlaczego należy wykonać takie połączenie.
Pochodząc z Pythona , trudno mi właściwie zrozumieć, dlaczego takie połączenie jest potrzebne. Mam na myśli, że mogłabym użyć Regex.Split
podobnej składni niż implementacja Pythona, ale musiałbym to zrobić kosztem mniejszej wydajności (czasu instalacji) dla dowolnej prostej rzeczy .
Zasadniczo moje pytanie brzmi: dlaczego, u diabła, nie możemy po prostu zrobić:
testString.Split("anotherString");
Zauważ, że nie sugeruję żadnego prototypu ani implementacji. Rozumiem, dlaczego nie można wdrożyć powyższej wersji, biorąc pod uwagę bieżący interfejs API. Moim celem było zrozumienie, dlaczego taki interfejs API mógł zostać utworzony, biorąc pod uwagę korzyści wynikające z powyższej składni. Na razie elastyczność wydaje się być celem prądu, String.Split
który ma sens, ale szczerze mówiąc, naprawdę myślałem, że gdzieś nastąpił jakiś wzrost wydajności. Chyba się myliłem.
źródło
testString.Split(",.;");
itestString.Split(new Char [] {',', '.', ';',);
które nie są tym samym.IEnumerable<char>
, gdy sugerowany przez Ciebie dodatkowy prototyp może w niektórych przypadkach wydawać się niejednoznaczny (czy ograniczasz go przez cały ciąg, czy też przez każdy z jego znaków?).testString.Split("anotherString");
, jestem całkiem pewny, że mogę powiedzieć, że oczekiwanym zachowaniem było ograniczenie całego łańcucha (anotherString
w tym przypadku).Odpowiedzi:
Czasami użyteczne jest dzielenie na więcej niż jeden znak / ciąg znaków, więc interfejs API pozwala zapewnić tablicę, zapewniając maksymalną elastyczność. W przypadku
char
s otrzymujesz zarówno prostotę składni, jak i elastyczność, ponieważ parametr jest oznaczony jako,params
więc możesz pisaćSplit('x')
zamiastSplit(new[]{'x'})
.Dlaczego więc nie ma podobnej opcji dla ciągów, umożliwiającej pisanie
Split("x")
?Jest to być może niefortunna konsekwencja projektowania interfejsu API. Początkowo dozwolone było tylko dzielenie znaków. Dzielenie ciągów zostało dodane w 2.0, prawdopodobnie dlatego, że jest bardziej skomplikowane do wdrożenia. Ale dodawanie
String.Split(string)
lubString.Split(string[])
przeciążanie nie było możliwe , ponieważ spowodowałoby to, że wyrażenie byłobytestString.Split(null)
niejednoznaczne, a kod nie byłby już kompilowany.testString.Split(null)
jest właściwie dość powszechnym idiomem, ponieważ dzieli ciąg znaków na białe znaki, więc takie złamanie byłoby zbyt powszechne, aby było możliwe do zaakceptowania.Używanie
null
parametru jako przełącznika specjalnego zachowania jest obecnie ogólnie uważane za zły projekt, więc myślę, że to sprawiedliwe, że ten interfejs API jest po prostu wadliwy.Nie ma
Split(string[], Int32)
też żadnego , prawdopodobnie z podobnego powodu - byłoby dwuznaczne,Split(char[], Int32)
gdyby pierwszym parametrem byłnull
. Tam są podobne przeciążenia zStringSplitOptions
parametrami, ale te były dodawane w tym samym czasie w 2,0, więc nie ma dwuznaczności został wprowadzony w istniejącym kodzie.Uwaga
Dla jasności, to tylko moja hipoteza, nie znam faktycznego myślenia projektantów frameworka .net.
źródło
Split(null)
jest to bezużyteczne, jeśli pozwoliszSplit("")
. Poza tym, że pozwoliłoby to na lepszą składnię, ta i tak jest bardziej gadatliwa ...String.Split(null)
nie będzie już niejednoznaczne, aby mogli dodać przeciążenieNie będąc autorem metod, nie wiem, dlaczego wybrano ten zestaw przeciążeń. Należy jednak zwrócić uwagę na dwie rzeczy:
Jeśli dzielisz na jeden znak,
public string[] Split(params char[] separator
można użyć wersji) w ten sposób:jak
char[]
toparams
parametr.Możesz łatwo dodać tutaj własną metodę rozszerzenia, aby osiągnąć to, co chcesz:
i teraz
testString.Split("anotherString");
będzie działać dla ciebie.źródło
String
klasy, obie byłyby możliwe. Czy się mylę ?Różne języki mają nieco inne reguły dotyczące niejawnych konwersji i przeciążenia, a .NET Framework został zaprojektowany do współpracy z dowolnym z nich. W
Option Strict Off
dialekcie VB.NET wartość typuString
może być przekazana do funkcji, która oczekujeChar[]
zachowania o wartości równoważnej wywołaniuToCharArray()
ciągu.Myślę, że rozsądną rzeczą byłoby mieć osobne nazwy dla
Split
(który akceptuje pojedynczyChar
lubString
) iSplitMulti
(który akceptujeChar[]
lubString[]
), ale .NET wydaje się czasem preferować używanie samego przeciążenia do wybierania różnych rodzajów operacji. Niestety nie wiem, w jaki sposób można zastosowaćString.Split
scenariusze użycia, które wymagałyby rozróżnienia różnych rodzajów ograniczników innych niż oddzielne rozdzielenie każdego z nich.Innym pominięciem jest opcja zachowania ograniczników, włączając je na końcu poprzedniego łańcucha lub na początku następnego łańcucha, lub mając elementy tablicy nieparzystej liczby, a elementy parzyste są między nimi.
źródło