Ciągi wielowierszowe w VB.NET


144

Czy istnieje sposób na posiadanie ciągów wielowierszowych w VB.NET, takich jak Python

a = """
multi
line
string
"""

czy PHP?

$a = <<<END
multi
line
string
END;

Oczywiście coś, co nie jest

"multi" & _
"line

1
BTW: '"multi" & _ <newline> "line" to jeden literał ciągu, a nie dwa. Jednak nadal jest brzydki.
Joel Coehoorn


Moje dwa centy: w VS 2017 skompilowano by twój kod VB.NET.
ᗩИ Ꭰ ЯƎᗩ

Odpowiedzi:


222

Możesz użyć literałów XML, aby osiągnąć podobny efekt:

Imports System.XML
Imports System.XML.Linq
Imports System.Core

Dim s As String = <a>Hello
World</a>.Value

Pamiętaj, że jeśli masz znaki specjalne, powinieneś użyć bloku CDATA:

Dim s As String = <![CDATA[Hello
World & Space]]>.Value

AKTUALIZACJA 2015:

Wieloliniowe literały ciągów zostały wprowadzone w języku Visual Basic 14 (w programie Visual Studio 2015 ). Powyższy przykład można teraz zapisać jako:

Dim s As String = "Hello
World & Space"

MSDN article isn't updated yet (as of 2015-08-01), so check some answers below for details.

Szczegóły są dodawane do repozytorium Roslyn New-Language-Features-in-VB-14 Github.


jak można tam zastąpić zmienne? np. „a =” & someint & ”,”
Christopher Mahan,

1
@Christopher - zazwyczaj bardziej czytelne jest umieszczanie tokenów w stałej ciągu, a następnie ich zastępowanie. Więc s="... a=~someint~ ..."i wtedy s=s.Replace("~someint~', SomeInt).
Herb Caudill,

Wydaje się, że to nie działa z kompilacją dynamiczną: CodeDomProvider.CreateProvider ("VisualBasic"). CompileAssemblyFromFile (<opcje>, <plik .vb z powyższą składnią trików>) ... Jakieś pomysły? Czy to tylko cukier syntaktyczny VS 2010?
Czad

1
@romkyns Nie prawda, wymyśliłem, jak używać CDATA i nadal mogę osadzać za pomocą <% =%> Zobacz tutaj
Nelson,

1
Niesamowite! Jak zachować wcięcia kodu bez wprowadzania go do literału w nowszej składni?
Panzercrisis

50

VB.Net ma taką funkcję, a to będzie nie przychodzić w Visual Studio 2010. Cechą jirwin jest refering nazywany jest niejawna linia kontynuacji. Ma to związek z usunięciem znaku _ z instrukcji lub wyrażenia wielowierszowego. Eliminuje to potrzebę kończenia ciągu wielowierszowego znakiem _, ale nadal nie ma literału ciągu wielowierszowego w VB.

Przykład ciągu wielowierszowego

Visual Studio 2008

Dim x = "line1" & vbCrlf & _
        "line2"

Visual Studio 2010

Dim x = "line1" & vbCrlf & 
        "line2"

Jak więc to działa w przypadku literałów XML? Albo jest to możliwe, albo literały XML używają innej techniki - a jeśli innej techniki, to takiej, którą można rozszerzyć na ciągi wieloliniowe.
mellamokb

1
Literały XML @mellamokb są ... wyjątkowe ze względu na brak lepszego słowa. Kompilator je rozumie i dlatego pozwoli im niejawnie obejmować wiele wierszy. Nie dodano takiej obsługi dla ciągów wieloliniowych. Dodanie takiej obsługi jest znacznie łatwiejsze niż literały XML, po prostu nie spełniło poprzeczki tego wydania.
JaredPar

38

Użyłem tego wariantu:

     Dim query As String = <![CDATA[
        SELECT 
            a.QuestionID
        FROM 
            CR_Answers a

        INNER JOIN 
            CR_Class c ON c.ClassID = a.ClassID
        INNER JOIN
            CR_Questions q ON q.QuestionID = a.QuestionID
        WHERE 
            a.CourseID = 1
        AND 
            c.ActionPlan = 1
        AND q.Q_Year = '11/12'
        AND q.Q_Term <= (SELECT CurrentTerm FROM CR_Current_Term)
    ]]>.Value()

dopuszcza <> w ciągu


1
Świetna technika, ale może być konieczne dodanie pewnych odniesień do projektu, aby działał. Zobacz: msdn.microsoft.com/en-us/library/bb531455%28v=vs.90%29.aspx i stackoverflow.com/a/28654126/3175562
Mike

30

Ciągi wielowierszowe są dostępne od wersji Visual Studio 2015.

Dim sql As String = "
    SELECT ID, Description
    FROM inventory
    ORDER BY DateAdded
"

Możesz je łączyć z interpolacją ciągów, aby zmaksymalizować użyteczność:

Dim primaryKey As String = "ID"
Dim inventoryTable As String = "inventory"

Dim sql As String = $"
    SELECT {primaryKey}, Description
    FROM {inventoryTable}
    ORDER BY DateAdded
"

Zauważ, że interpolowane ciągi rozpoczynają się $i trzeba się zająć ", {a }zawarte w środku - przekształcenie ich "", {{albo }}odpowiednio.

Tutaj możesz zobaczyć faktyczne podświetlanie składni interpolowanych części powyższego przykładu kodu:

wprowadź opis obrazu tutaj

Jeśli zastanawiasz się, czy ich rozpoznawanie przez edytor Visual Studio działa również z refaktoryzacją (np. Masową zmianą nazw zmiennych), to masz rację, refaktoryzacja kodu działa z nimi. Nie wspominając o tym, że obsługują również technologię IntelliSense, zliczanie odwołań lub analizę kodu.


20

Wielowierszowe literały ciągów są wprowadzane w Visual Basic 14.0 - https://roslyn.codeplex.com/discussions/571884

Możesz użyć tego w wersji zapoznawczej VS2015, która jest już dostępna - http://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs (pamiętaj, że nadal możesz używać VS2015, nawet jeśli celujesz w starszą wersja platformy .NET)

Dim multiline = "multi
line
string"

Ciągi VB są teraz w zasadzie takie same jak ciągi C # dosłowne - nie obsługują sekwencji ucieczki z ukośnikiem odwrotnym, takich jak \ n, i zezwalają na znaki nowej linii w ciągu, a symbol cudzysłowu jest zastępowany podwójnymi cudzysłowami ""


2
Dziękuję Lucian za dodanie wieloliniowych ciągów do VB. Może możesz zaktualizować swoją odpowiedź, ponieważ VS 2015 to teraz RTM. A może możesz też nakłonić kogoś w swojej firmie, aby zaktualizował powiązany artykuł MSDN .
miroxlav

14

był to dla mnie bardzo pomocny artykuł, ale nikt nie wspomniał o tym, jak łączyć w przypadku, gdy chcesz wysłać jakieś zmienne, co musisz robić w 99% przypadków.

... <% = zmienna %> ...

Oto jak to robisz:

<SQL> SELECT * FROM MyTable WHERE FirstName='<%= EnteredName %>' </SQL>.Value


17
W takim przypadku chcesz uniknąć konkatenacji i zamiast tego używać parametrów SQL, ponieważ lepiej chronią przed atakami iniekcji SQL. Widzę, że jest to przydatne do dynamicznego generowania kodu SQL (bez przekazywania danych wejściowych użytkownika).
Chad Levy,

10

Cóż, skoro wydajesz się być na swoim Pythonie, mogę zasugerować skopiowanie tekstu do Pythona, na przykład:

 s="""this is gonna 
last quite a 
few lines"""

następnie wykonaj:

  for i in s.split('\n'):
    print 'mySB.AppendLine("%s")' % i

#    mySB.AppendLine("this is gonna")
#    mySB.AppendLine("last quite a")
#    mySB.AppendLine("few lines")

lub

  print ' & _ \n'.join(map(lambda s: '"%s"' % s, s.split('\n')))

#    "this is gonna" & _ 
#    "last quite a" & _ 
#    "few lines"

wtedy przynajmniej możesz to skopiować i umieścić w swoim kodzie VB. Dodatkowe punkty, jeśli przypiszesz skrót klawiszowy (najszybszy do uzyskania za pomocą: Autohotkey ), aby zrobić to dla wszystkiego, co znajduje się w twoim buforze wklejania. Ten sam pomysł działa dobrze w przypadku programu formatującego SQL.


8

Wieloliniowe literały ciągów w vb.net przy użyciu klasy XElement.

Imports System.Xml.Linq

Public Sub Test()

dim sOderBy as string = ""

dim xe as XElement = <SQL>
                SELECT * FROM <%= sTableName %>
                 <ORDER_BY> ORDER BY <%= sOrderBy %></ORDER_BY>
                 </SQL>

'** conditionally remove a section 
if sOrderBy.Length = 0 then xe.<ORDER BY>.Remove

'** convert XElement value to a string 
dim sSQL as String = xe.Value

End Sub

7

To jest dla mnie najbardziej irytujące w VB jako języku. Poważnie, kiedyś napisałem ciąg w pliku i napisałem kod w następujący sposób:

Dim s as String = file_get_contents("filename.txt")

tylko po to, aby móc przetestować zapytanie bezpośrednio na serwerze SQL, jeśli zajdzie taka potrzeba.

Moja obecna metoda polega na użyciu procedury składowanej na serwerze SQL i po prostu wywołanie tego, aby móc przekazać parametry do zapytania itp.


5

Dowiedziałem się, jak używać obu <! [CDATA [wraz z <% = dla zmiennych, co pozwala ci kodować bez obaw.

Zasadniczo musisz zakończyć tagi CDATA przed zmienną VB, a następnie ponownie dodać ją po, aby CDATA nie przechwytywał kodu VB. Musisz owinąć cały blok kodu w znacznik, ponieważ będziesz mieć wiele bloków CDATA.

Dim script As String = <code><![CDATA[
  <script type="text/javascript">
    var URL = ']]><%= domain %><![CDATA[/mypage.html';
  </script>]]>
</code>.value

3

Możesz (powinieneś?) Umieścić ciąg w pliku zasobów (np. „Mój projekt” / Zasoby), a następnie pobrać go za pomocą

 Dim a = My.Resources.Whatever_you_chose

3

Zastrzeżenie: uwielbiam Pythona. Wieloliniowe ciągi to tylko jeden powód.

Ale robię też VB.Net, więc oto mój skrót do bardziej czytelnych długich ciągów.

  Dim lines As String() = {
    "Line 1",
    "Line 2",
    "Line 3"
  }
  Dim s As String = Join(lines, vbCrLf)

1
Potrzebujesz znaku _ na końcu linii dla każdego „wiersza…”, który wygląda brzydko.
Kenji Noguchi,

2
Właściwie nie. Późniejsze wersje VB (2010 i nowsze chyba?) Nie wymagają znaku _ w wielu przypadkach, w tym w przykładzie pokazanym tutaj.
Darryl,

2

możesz użyć do tego XML

dim vrstr as string = <s>
    some words
    some words
    some
    words
</s>

1

w Visual Studio 2010 (VB NET) próbuję wykonać następujące czynności i działa dobrze

Dim HtmlSample As String = <anything>what ever you want to type here with multiline strings</anything>

dim Test1 as string =<a>onother multiline example</a>


0

Jeśli potrzebujesz literału XML w VB.Net ze zmienną kodu linii, możesz to zrobić w następujący sposób:

<Tag><%= New XCData(T.Property) %></Tag>

Zwróć uwagę, dlaczego wspominasz tutaj o literale XML, nie widzisz XML wspomnianego w oryginalnym pytaniu.
Kmeixner

0

Możesz także użyć System.Text.StringBuilderclass w ten sposób:

Dim sValue As New System.Text.StringBuilder
sValue.AppendLine("1st Line")
sValue.AppendLine("2nd Line")
sValue.AppendLine("3rd Line")

Następnie otrzymujesz ciąg wielowierszowy za pomocą:

sValue.ToString()

-1

Ponieważ jest to problem z czytelnością, użyłem następującego kodu:

MySql = ""
MySql = MySql & "SELECT myTable.id"
MySql = MySql & " FROM myTable"
MySql = MySql & " WHERE myTable.id_equipment = " & lblId.Text

1
To jest złe. Właśnie utworzyłeś 4 wystąpienia ciągu
TS

Odziedziczyłem starszy kod VB6, który muszę przenieść na VB.NET, który jest ich pełen! :( W tym przypadku wolę poświęcić wydajność, aby zachować czytelność.
Zac

Nie musisz. Zawsze możesz konkatenować bez ponownego przypisywania zmiennej i formatować w tych wierszach
TS

W moim przypadku nie ma zastosowania, aby przełączyć się na poprawną składnię, ponieważ powinienem zmodyfikować cały kod i nie ma czasu na projekt.
Zac

-1

Użyj vbCrLflub vbNewLine. Działa z MessageBoxami i wieloma innymi kontrolkami, które testowałem.

Dim str As String
str = "First line" & vbCrLf & "Second line"
MsgBox(str)
str = "First line" & vbNewLine & "Second line"
MsgBox(str)

Pokaże dwa identyczne MessageBoxes z 2 liniami.


-9

Nie, VB.NET nie ma jeszcze takiej funkcji. Będzie dostępny w następnej iteracji VB (Visual Basic 10), jednak ( link )


Jesteś pewien? Wiem, że pozwolą na wielowierszowe instrukcje, ale czy pozwolą też na wielowierszowe łańcuchy ? Mam na myśli "witaj <newline> świecie"?
Mehrdad Afshari

1
Usuwanie znaku kontynuacji wiersza i wielowierszowych ciągów literałów to różne funkcje.
JaredPar

-16

jeśli jest jak C # (nie mam zainstalowanego VB.Net), możesz poprzedzić ciąg znakiem @

foo = @"Multiline
String"

jest to również przydatne w przypadku takich rzeczy jak @ "C: \ Windows \ System32 \" - zasadniczo wyłącza ucieczkę i włącza multilinię.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.