string query =@"SELECT foo, bar
FROM table
WHERE id = 42";
Nie musisz także uciekać przed znakami specjalnymi , korzystając z tej metody, z wyjątkiem podwójnych cudzysłowów, jak pokazano w odpowiedzi Jona Skeeta.
W każdym razie jest to dosłowny ciąg znaków - jest to dosłowny ciąg znaków ze znakiem @.
Jon Skeet,
95
jeśli ciąg zawiera podwójne cudzysłowy ( "), można uciec im tak:«»(to dwa znaki cudzysłowu)
Muad'Dib
8
Czy istnieje sposób na wykonanie powyższego bez tworzenia nowych linii? Mam naprawdę długi fragment tekstu, który chciałbym zobaczyć zawinięty w IDE bez konieczności używania znaku plus („cześć” + „tam”).
noelicus,
2
@ noelicus - nie bardzo, ale można to obejść, stosując powyższą technikę weiqure:@"my string".Replace(Environment.NewLine, "")
John Rasch,
8
@afsharm Możesz użyć $ @ „text”
Patrick McDonald
566
W języku C # nazywa się to dosłowne dosłowne ciągi literalne , a kwestią jest umieszczenie @ przed literałem. Pozwala to nie tylko na wiele linii, ale także wyłącza ucieczkę. Na przykład możesz wykonać:
string query =@"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
Obejmuje to jednak podział wiersza (przy użyciu dowolnego podziału wiersza, jaki ma je źródło) w ciągu. W przypadku SQL jest to nie tylko nieszkodliwe, ale prawdopodobnie poprawia czytelność w dowolnym miejscu łańcucha - ale w innych miejscach może nie być wymagane, w takim przypadku albo nie musisz używać dosłownego ciągu literowego o wielu wierszach, lub usuń je z powstałego ciągu.
Jedyną różnicą jest to, że jeśli chcesz podwójnego cudzysłowu, musisz dodać dodatkowy symbol podwójnego cudzysłowu:
string quote =@"Jon said, ""This will work,"" - and it did!";
Ta odpowiedź jest niepoprawna; wprowadza nowe linie, których OP nie chce.
TamaMcGlinn
@TamaMcGlinn: Dodam coś do odpowiedzi na ten temat - nie było jasne, kiedy OP napisało pytanie.
Jon Skeet
105
Problem z używaniem literału ciągów, który znajduję, polega na tym, że może sprawić, że twój kod będzie wyglądał „ dziwnie ”, ponieważ aby nie uzyskać spacji w samym ciągu, należy go całkowicie wyrównać:
var someString =@"The
quick
brown
fox...";
Fuj
Tak więc rozwiązaniem, które lubię używać, dzięki czemu wszystko ładnie dopasowuje się do reszty kodu:
var someString =String.Join(Environment.NewLine,"The","quick","brown","fox...");
I oczywiście, jeśli chcesz po prostu logicznie podzielone wiersze instrukcji SQL jak jesteś i w rzeczywistości nie potrzebują nowej linii, zawsze można po prostu zastąpić Environment.NewLineza " ".
Dużo czystsze, dzięki. String.Concat działa również podobnie i nie wymaga separatora.
Seth
Dzięki. Podoba mi się String.Join z ogranicznikiem „” dla SQL, ponieważ pozwala on na wcięcia / dopasowywanie paren i unika konieczności dodawania początkowej spacji.
Rob na TVSeries.com
7
Choć brzydka, pierwsza wersja nie wymaga kodu do uruchomienia . Druga opcja oczywiście ma narzut związany z wykonywaniem w celu połączenia poszczególnych ciągów.
Gone Coding
@GoneCoding, jesteś tego pewien? Kompilator może zoptymalizować konkatenację.
William Jockusch
@WilliamJockusch: generalnie wywołania funkcji innych niż operator (jak łączenie) pozostają nietknięte i nie są zoptymalizowane. Najlepiej sprawdź skompilowany kod, ale położyłbym pieniądze, że połączenie nie jest zoptymalizowane.
Gone Coding
104
Inną sprawą, na którą trzeba uważać, jest użycie literałów łańcuchowych w łańcuchu znaków. W takim przypadku musisz uciec nawiasom klamrowym / nawiasom klamrowym „{” i „}”.
// this would give a format exceptionstring.Format(@"<script> function test(x)
{ return x * {0} } </script>", aMagicValue)// this contrived example would workstring.Format(@"<script> function test(x)
{{ return x * {0} }} </script>", aMagicValue)
A jaką to robi różnicę? Z lub bez „@” musisz podwoić „{{”, aby otrzymać „{” jako znak do wydrukowania, jest to format String.Format, a nie treść ciągu.
greenoldman
12
Jest to godna uwagi gotcha dla osób, które chcą wstawić kod JavaScript w łańcuch, co może być wykonywane częściej w dosłownym dosłownym łańcuchu niż w zwykłych ciągach.
Ed Brannin
2
W nowej wersji C # 6.0 można używać indeksowanego operatora właściwości wraz z dosłownym ciągiem literalnym (np. $ @ „Wartość to {this.Value}”;)
Heliac
2
@Heliac Myślę, że masz na myśli interpolowane ciągi znaków, które również mogą być dosłowne w tej składni. var query = $ @ "wybierz foo, pasek z tabeli gdzie id = {id}";
Brianary
102
Na marginesie, w C # 6.0 możesz teraz łączyć interpolowane ciągi z dosłownym dosłownym ciągiem:
Fajnie, do tej pory o tym nie wiedziałem. Jeśli ktoś jest zainteresowany: $ thingy nazywa się „Interpolated Strings” i możesz przeczytać o tym szczegółowo tutaj: msdn.microsoft.com/en-us/library/dn961160.aspx
Hauke P.
tx, poprawiono sformułowanie
Heliac
1
Zakładam, że dosłowne nawiasy klamrowe muszą zostać podwojone, np. $@"{{example literal text { fooString }. }}" Może to trochę pomylić, ponieważ Angular, React i Vue.js używają przeciwnej konwencji.
Patrick Szalapski
58
Dlaczego ludzie mylą ciągi z literałami ciągu? Przyjęta odpowiedź jest świetną odpowiedzią na inne pytanie; nie do tego.
Wiem, że to stary temat, ale przyszedłem tutaj z prawdopodobnie tym samym pytaniem co OP, i frustrujące jest obserwowanie, jak ludzie wciąż go błędnie interpretują. A może źle to rozumiem, nie wiem.
Z grubsza mówiąc, ciąg znaków to obszar pamięci komputera, który podczas wykonywania programu zawiera sekwencję bajtów, które można odwzorować na znaki tekstowe. Z drugiej strony, literał ciągu znaków jest fragmentem kodu źródłowego, który nie został jeszcze skompilowany i reprezentuje wartość użytą do zainicjowania ciągu znaków później podczas wykonywania programu, w którym się pojawia.
W języku C # instrukcja ...
string query ="SELECT foo, bar"+" FROM table"+" WHERE id = 42";
... nie produkuje trzywierszowego sznurka, ale jedną wkładkę; konkatenacja trzech łańcuchów (każdy zainicjowany z innego literału), z których żaden nie zawiera modyfikatora nowej linii.
To, o co OP wydaje się pytać - a przynajmniej to, o co pytałbym tymi słowami - nie polega na tym, jak wprowadzić w skompilowanym ciągu znaków podział wierszy naśladujący te znajdujące się w kodzie źródłowym, ale na jak długo rozdzielić dla zachowania przejrzystości , pojedynczy wiersz tekstu w kodzie źródłowym bez wprowadzania przerw w skompilowanym ciągu. I nie wymagając dłuższego czasu wykonywania, spędziłem dołączając do wielu podciągów pochodzących z kodu źródłowego. Podobnie jak końcowe ukośniki odwrotne w literale ciągu wielowierszowego w javascript lub C ++.
Sugerowanie użycia dosłownych ciągów, nieistotnych StringBuilders, s, String.Joina nawet funkcji zagnieżdżonych z odwracaniem ciągów, a co nie, sprawia, że myślę, że ludzie tak naprawdę nie rozumieją pytania. A może nie rozumiem tego.
O ile mi wiadomo, C # nie ma (przynajmniej w wersji paleolitycznej, której wciąż używam, z poprzedniej dekady) funkcji czystego generowania wieloliniowych literałów łańcuchowych, które można rozwiązać podczas kompilacji, a nie wykonywania.
Być może obecne wersje to obsługują, ale pomyślałem, że podzielę różnicę, którą dostrzegam między łańcuchami i literałami łańcucha.
AKTUALIZACJA:
(Od komentarza MeowCat2012) Możesz. Podejście „+” OP jest najlepsze. Zgodnie ze specyfikacją gwarantowana jest optymalizacja: http://stackoverflow.com/a/288802/9399618
Zamieszanie, jakie niektórzy (w tym ja) mogliby mieć patrząc na pierwotne pytanie, polega na tym, że format tutaj-doc (shell, php, perl, ...) zawiera znaki nowej linii. Więc jeśli PO porównuje się do heredoc PHP, to włączenie nowych linii nie powinno być problemem.
Tanktalus
Dokładnie. O ile wiem, twoja odpowiedź „nie, nie możesz tego zrobić w C #” jest poprawna.
TamaMcGlinn
Powiedziano mi, że w Javie taki połączony ciąg stanie się literałem pojedynczego ciągu w skompilowanym kodzie bajtowym. Może dot Net też to robi?
Meow Cat 2012
2
Możesz. Podejście „+” OP jest najlepsze. Zgodnie ze specyfikacją optymalizacja jest gwarantowana: stackoverflow.com/a/288802/9399618 Nadal jesteś jednym z niewielu, którzy rozumieją to pytanie. Czy byłoby możliwe usunięcie lub złożenie potencjalnie wprowadzających w błąd, ale zaakceptowanych odpowiedzi?
Meow Cat 2012
1
Dzięki za podpowiedź, @ MeowCat2012. Patrząc na jakiś zdekompilowany kod, wydaje się, że rzeczywiście tak jest.
Carvo Loco
12
Nie widziałem tego, więc opublikuję go tutaj (jeśli chcesz przekazać ciąg znaków, możesz to zrobić). Pomysł polega na tym, że możesz podzielić ciąg na wiele wierszy i dodać własną treść (również na wielu liniach) w dowolny sposób. Tutaj „tableName” można przekazać do ciągu.
privatestring createTableQuery ="";void createTable(string tableName){
createTableQuery =@"CREATE TABLE IF NOT EXISTS
["+ tableName +@"] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Key] NVARCHAR(2048) NULL,
[Value] VARCHAR(2048) NULL
)";}
dość niebezpieczne, powiedziałbym: łatwo zrobić komuś zastrzyk w ten sposób.
Kai
4
Jest w porządku, o ile wiesz, że wszystkie twoje zmienne (jeśli istnieją!) W ciągu zapytania pochodzą ze stałych kodu lub innego bezpiecznego źródła - np. createTable("MyTable"); W każdym razie pytanie OP dotyczyło sposobu wprowadzania literałów ciągu wielowierszowego bezpośrednio w kodzie , a nie jak konstruować zapytania do bazy danych per se. :)
dbeachy1
2
powinien prawdopodobnie użyć konstruktora ciągów, szczególnie jeśli liczba plusów (+) jest duża.
Powinieneś wyjaśnić, co robi każdy, ponieważ @ oznacza dosłowny ciąg, a „” oznacza unikanie podwójnych cudzysłowów.
AFract
4
Tak, możesz podzielić ciąg na wiele wierszy bez wprowadzania nowych wierszy do rzeczywistego ciągu, ale nie jest ładny:
string s = $@"Thisstring{string.Empty} contains no newlines{string.Empty} even though it is spread onto{string.Empty} multiple lines.";
Sztuką jest wprowadzenie kodu, który ewaluuje do pustego, a kod ten może zawierać znaki nowej linii bez wpływu na wynik. Dostosowałem to podejście z tej odpowiedzi do podobnego pytania.
Wygląda na to, że istnieje pewne zamieszanie co do pytania, ale istnieją dwie wskazówki, że chcemy tutaj dosłowny ciąg znaków nie zawierający żadnych znaków nowego wiersza, którego definicja obejmuje wiele wierszy. (w komentarzach tak mówi, a „oto co mam” pokazuje kod, który nie tworzy łańcucha z nowymi liniami)
Zmień powyższą definicję zapytania, tak aby był to jeden literał łańcuchowy, zamiast łączenia dwóch literałów łańcuchowych, które kompilator może zoptymalizować w kompilatorze.
Podejście C ++ polega na kończeniu każdego wiersza odwrotnym ukośnikiem, co powoduje, że znak nowej linii jest zastępowany i nie pojawia się na wyjściu. Niestety nadal istnieje problem polegający na tym, że każda linia po pierwszej musi być wyrównana, aby nie dodawać dodatkowych białych znaków do wyniku.
Jest tylko jedna opcja, która nie polega na optymalizacjach kompilatora, które mogą się nie zdarzyć, czyli umieszczenie definicji w jednym wierszu. Jeśli chcesz polegać na optymalizacjach kompilatora, + już masz świetny; nie musisz wyrównywać łańcucha w lewo, w wyniku nie otrzymujesz nowego wiersza, a to tylko jedna operacja, brak wywołań funkcji, aby oczekiwać optymalizacji.
Twórczy. Wydaje się jednak, że (niepotwierdzone) byłoby to traktowane jako ciąg formatu i może być zoptymalizowane. Z drugiej strony podejście „+” OP jest najlepsze. Zgodnie ze specyfikacją optymalizacja jest gwarantowana: stackoverflow.com/a/288802/9399618
Meow Cat 2012
4
Dodaj wiele wierszy: użyj @
string query =@"SELECT foo, bar
FROM table
WHERE id = 42";
Dodaj wartości ciągu do środka: użyj $
string text ="beer";string query = $"SELECT foo {text} bar ";
Ciąg wielu linii Dodaj wartości do środka: użyj $ @
string text ="Customer";string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id =42";
Jeśli nie chcesz spacji / znaków nowej linii, wydaje się, że dodawanie ciągów działa:
var myString =String.Format("hello "+"world"+" i am {0}"+" and I like {1}.",
animalType,
animalPreferenceType
);// hello world i am a pony and I like other ponies.
Jedną z (nieumyślnie wykazanych) wad tego podejścia jest to, że musisz bardzo uważać, aby uwzględnić miejsca, w których chcesz. Poleciłbym bardziej spójne podejście niż ja (np. Zawsze na początku linii).
rattray
string + string jest jednak tym, od czego zaczął OP.
TamaMcGlinn
1
Wiem, że jestem trochę spóźniony na imprezę, ale chcę polecić https://www.buildmystring.com/ przyszłym czytelnikom tego wątku. Za pomocą tej strony możesz przekonwertować dowolny kod na literał ciąg C #.
42
parametru jako parametru, zwłaszcza jeśli pochodzi on z danych wejściowych użytkownika, aby uniknąć wstrzyknięcia SQL.Odpowiedzi:
Możesz użyć
@
symbolu przed a,string
aby utworzyć dosłowny ciąg literału :Nie musisz także uciekać przed znakami specjalnymi , korzystając z tej metody, z wyjątkiem podwójnych cudzysłowów, jak pokazano w odpowiedzi Jona Skeeta.
źródło
@"my string".Replace(Environment.NewLine, "")
W języku C # nazywa się to dosłowne dosłowne ciągi literalne , a kwestią jest umieszczenie @ przed literałem. Pozwala to nie tylko na wiele linii, ale także wyłącza ucieczkę. Na przykład możesz wykonać:
Obejmuje to jednak podział wiersza (przy użyciu dowolnego podziału wiersza, jaki ma je źródło) w ciągu. W przypadku SQL jest to nie tylko nieszkodliwe, ale prawdopodobnie poprawia czytelność w dowolnym miejscu łańcucha - ale w innych miejscach może nie być wymagane, w takim przypadku albo nie musisz używać dosłownego ciągu literowego o wielu wierszach, lub usuń je z powstałego ciągu.
Jedyną różnicą jest to, że jeśli chcesz podwójnego cudzysłowu, musisz dodać dodatkowy symbol podwójnego cudzysłowu:
źródło
Problem z używaniem literału ciągów, który znajduję, polega na tym, że może sprawić, że twój kod będzie wyglądał „ dziwnie ”, ponieważ aby nie uzyskać spacji w samym ciągu, należy go całkowicie wyrównać:
Fuj
Tak więc rozwiązaniem, które lubię używać, dzięki czemu wszystko ładnie dopasowuje się do reszty kodu:
I oczywiście, jeśli chcesz po prostu logicznie podzielone wiersze instrukcji SQL jak jesteś i w rzeczywistości nie potrzebują nowej linii, zawsze można po prostu zastąpić
Environment.NewLine
za" "
.źródło
Inną sprawą, na którą trzeba uważać, jest użycie literałów łańcuchowych w łańcuchu znaków. W takim przypadku musisz uciec nawiasom klamrowym / nawiasom klamrowym „{” i „}”.
źródło
Na marginesie, w C # 6.0 możesz teraz łączyć interpolowane ciągi z dosłownym dosłownym ciągiem:
źródło
$@"{{example literal text { fooString }. }}"
Może to trochę pomylić, ponieważ Angular, React i Vue.js używają przeciwnej konwencji.Dlaczego ludzie mylą ciągi z literałami ciągu? Przyjęta odpowiedź jest świetną odpowiedzią na inne pytanie; nie do tego.
Wiem, że to stary temat, ale przyszedłem tutaj z prawdopodobnie tym samym pytaniem co OP, i frustrujące jest obserwowanie, jak ludzie wciąż go błędnie interpretują. A może źle to rozumiem, nie wiem.
Z grubsza mówiąc, ciąg znaków to obszar pamięci komputera, który podczas wykonywania programu zawiera sekwencję bajtów, które można odwzorować na znaki tekstowe. Z drugiej strony, literał ciągu znaków jest fragmentem kodu źródłowego, który nie został jeszcze skompilowany i reprezentuje wartość użytą do zainicjowania ciągu znaków później podczas wykonywania programu, w którym się pojawia.
W języku C # instrukcja ...
... nie produkuje trzywierszowego sznurka, ale jedną wkładkę; konkatenacja trzech łańcuchów (każdy zainicjowany z innego literału), z których żaden nie zawiera modyfikatora nowej linii.
To, o co OP wydaje się pytać - a przynajmniej to, o co pytałbym tymi słowami - nie polega na tym, jak wprowadzić w skompilowanym ciągu znaków podział wierszy naśladujący te znajdujące się w kodzie źródłowym, ale na jak długo rozdzielić dla zachowania przejrzystości , pojedynczy wiersz tekstu w kodzie źródłowym bez wprowadzania przerw w skompilowanym ciągu. I nie wymagając dłuższego czasu wykonywania, spędziłem dołączając do wielu podciągów pochodzących z kodu źródłowego. Podobnie jak końcowe ukośniki odwrotne w literale ciągu wielowierszowego w javascript lub C ++.
Sugerowanie użycia dosłownych ciągów, nieistotnych
StringBuilder
s, s,String.Join
a nawet funkcji zagnieżdżonych z odwracaniem ciągów, a co nie, sprawia, że myślę, że ludzie tak naprawdę nie rozumieją pytania. A może nie rozumiem tego.O ile mi wiadomo, C # nie ma (przynajmniej w wersji paleolitycznej, której wciąż używam, z poprzedniej dekady) funkcji czystego generowania wieloliniowych literałów łańcuchowych, które można rozwiązać podczas kompilacji, a nie wykonywania.
Być może obecne wersje to obsługują, ale pomyślałem, że podzielę różnicę, którą dostrzegam między łańcuchami i literałami łańcucha.
AKTUALIZACJA:
(Od komentarza MeowCat2012) Możesz. Podejście „+” OP jest najlepsze. Zgodnie ze specyfikacją gwarantowana jest optymalizacja: http://stackoverflow.com/a/288802/9399618
źródło
Nie widziałem tego, więc opublikuję go tutaj (jeśli chcesz przekazać ciąg znaków, możesz to zrobić). Pomysł polega na tym, że możesz podzielić ciąg na wiele wierszy i dodać własną treść (również na wielu liniach) w dowolny sposób. Tutaj „tableName” można przekazać do ciągu.
źródło
createTable("MyTable");
W każdym razie pytanie OP dotyczyło sposobu wprowadzania literałów ciągu wielowierszowego bezpośrednio w kodzie , a nie jak konstruować zapytania do bazy danych per se. :)Możesz użyć @ i „” .
źródło
Tak, możesz podzielić ciąg na wiele wierszy bez wprowadzania nowych wierszy do rzeczywistego ciągu, ale nie jest ładny:
Sztuką jest wprowadzenie kodu, który ewaluuje do pustego, a kod ten może zawierać znaki nowej linii bez wpływu na wynik. Dostosowałem to podejście z tej odpowiedzi do podobnego pytania.
Wygląda na to, że istnieje pewne zamieszanie co do pytania, ale istnieją dwie wskazówki, że chcemy tutaj dosłowny ciąg znaków nie zawierający żadnych znaków nowego wiersza, którego definicja obejmuje wiele wierszy. (w komentarzach tak mówi, a „oto co mam” pokazuje kod, który nie tworzy łańcucha z nowymi liniami)
Ten test jednostkowy pokazuje zamiar:
Zmień powyższą definicję zapytania, tak aby był to jeden literał łańcuchowy, zamiast łączenia dwóch literałów łańcuchowych, które kompilator może zoptymalizować w kompilatorze.
Podejście C ++ polega na kończeniu każdego wiersza odwrotnym ukośnikiem, co powoduje, że znak nowej linii jest zastępowany i nie pojawia się na wyjściu. Niestety nadal istnieje problem polegający na tym, że każda linia po pierwszej musi być wyrównana, aby nie dodawać dodatkowych białych znaków do wyniku.
Jest tylko jedna opcja, która nie polega na optymalizacjach kompilatora, które mogą się nie zdarzyć, czyli umieszczenie definicji w jednym wierszu. Jeśli chcesz polegać na optymalizacjach kompilatora, + już masz świetny; nie musisz wyrównywać łańcucha w lewo, w wyniku nie otrzymujesz nowego wiersza, a to tylko jedna operacja, brak wywołań funkcji, aby oczekiwać optymalizacji.
źródło
Dodaj wiele wierszy: użyj @
Dodaj wartości ciągu do środka: użyj $
Ciąg wielu linii Dodaj wartości do środka: użyj $ @
źródło
Jeśli nie chcesz spacji / znaków nowej linii, wydaje się, że dodawanie ciągów działa:
Możesz uruchomić powyższe , jeśli chcesz.
źródło
Wiem, że jestem trochę spóźniony na imprezę, ale chcę polecić https://www.buildmystring.com/ przyszłym czytelnikom tego wątku. Za pomocą tej strony możesz przekonwertować dowolny kod na literał ciąg C #.
źródło
Możesz użyć tych dwóch metod:
W SplitLineToMultiline () musisz zdefiniować ciąg, którego chcesz użyć, a długość wiersza jest bardzo prosta. Dziękuję Ci .
źródło