For as long as I can remember, VB.NET programmers have had to deal with the frustration of multiline strings. I remember programming in ASP.NET and creating long functions which used a StringBuilder to put together my Strings. It was tedious, hard to read and harder to edit.

I've always liked C#'s multiline string literal capabilities, but VB by its very nature could never support such a construct (it would violate the basic syntax rules we've all come to know and love). I was glad to see the elimination of underscores in many scenarios (an ugly, overbearing line continuation marker that just added insult to injury), but the basic look and feel of multiline strings basically hasn't changed.

Dim sourceText As String =
    "Imports Microsoft.VisualBasic" & vbNewLine &
    "Imports System" & vbNewLine &
    "Imports System.Collections" & vbNewLine &
    "Imports Microsoft.Win32" & vbNewLine &
    "Imports System.Linq" & vbNewLine &
    "Imports System.Text" & vbNewLine &
    "Imports Roslyn.Compilers" & vbNewLine &
    "Imports System.ComponentModel" & vbNewLine &
    "Imports System.Runtime.CompilerServices" & vbNewLine &
    "Imports Roslyn.Compilers.VisualBasic" & vbNewLine &
    vbNewLine &
    "Namespace HelloWorld" & vbNewLine &
    "  Module Program" & vbNewLine &
    "    Sub Main(args As String())" & vbNewLine &
    "      Console.WriteLine(""Hello, World!"")" & vbNewLine &
    "    End Sub" & vbNewLine &
    "  End Module" & vbNewLine &
    "End Namespace"

Until XML Literals.

I was recently perusing the new Roslyn project website when I noticed a very clever and novel way to support multiline strings in VB.NET. As hinted at in the code above, Roslyn is capable of code analysis (among many, many other things), which requires you to feed it some code. Normally you'd probably put the code you want to analyze in its own file and use a StreamReader to serve it up to Roslyn, but that would be too complicated for the code examples on the website. As an alternative, I discovered the following syntax:

Dim sourceText As String =
    <string>
        Imports Microsoft.VisualBasic
        Imports System
        Imports System.Collections
        Imports Microsoft.Win32
        Imports System.Linq
        Imports System.Text
        Imports Roslyn.Compilers
        Imports System.ComponentModel
        Imports System.Runtime.CompilerServices
        Imports Roslyn.Compilers.VisualBasic
        
        Namespace HelloWorld
          Module Program
            Sub Main(args As String())
              Console.WriteLine("Hello, World!")
            End Sub
          End Module
        End Namespace
    </string>

At first I thought that the "string" tag may be special, but you can use any name you want. Converting an XElement to a String renders the content only. If you prefer type inference, you can use this syntax:

Dim sourceText =
    <string>
        Imports Microsoft.VisualBasic
        Imports System
        Imports System.Collections
        Imports Microsoft.Win32
        Imports System.Linq
        Imports System.Text
        Imports Roslyn.Compilers
        Imports System.ComponentModel
        Imports System.Runtime.CompilerServices
        Imports Roslyn.Compilers.VisualBasic
        
        Namespace HelloWorld
          Module Program
            Sub Main(args As String())
              Console.WriteLine("Hello, World!")
            End Sub
          End Module
        End Namespace
    </string>.Value

Some clean up will be required. For example, all white-space is preserved (including indentations) and you'll probably want to remove the leading and trailing spaces. If you want a string that you could print directly to a Console or Message Box window without having to edit, you'll need to use something like the following format:

Dim sourceText = <string>Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports Microsoft.Win32
Imports System.Linq
Imports System.Text
Imports Roslyn.Compilers
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports Roslyn.Compilers.VisualBasic

Namespace HelloWorld
  Module Program
    Sub Main(args As String())
      Console.WriteLine("Hello, World!")
    End Sub
  End Module
End Namespace</string>.Value
推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"