如何将VB.Net 12中的多行追加合并到单个AppendFormat

时间:2019-01-12 14:23:29

标签: c# vb.net stringbuilder

我正在使用VB.Net 12,因此不允许多行字符串,就像在C#中一样。

我在VB.Net中有以下代码,需要将其转换为单个AppendFormat。在C#中,这很容易,因为长字符串可以分布在多行上,以提高可读性/维护性,但是在VB.Net中,如果不使用&运算符来连接字符串,这似乎是不可能的。但是后来使用StringBuilder的目的就失败了。

问题

是否可以在不使用字符串连接运算符AppendFormat的情况下将以下VB.Net转换为使用单个&

'use a stringbuilder for better string performance
Dim sb As New StringBuilder()
sb.Append("<html>")
sb.Append("<head><style>body {font-size:10pt; font-family:Arial, Sans Serif;} table{margin:0; padding:0; border-collapse:collapse;} td{border:solid 1px #eee; padding:2px;}")
sb.Append(".m{color:#f00; font-weight:bold; font-size:14pt; margin-bottom:9px;} .t{width:120px; font-weight:bold; font-size:8pt;} .d{width:500px;}")
sb.Append("</style></head>")
sb.Append("<body>")
sb.AppendFormat("<div class='m'> {0} </div><table>", ex.Message.ToString())
sb.AppendFormat("<tr><td class='t'>REQUEST URL</td><td class='d'> {0} </td></tr>", currentContext.Request.Url.OriginalString)
sb.AppendFormat("<tr><td class='t'>REQUEST PATH</td><td class='d'> {0} </td></tr>", currentContext.Request.Path)
sb.AppendFormat("<tr><td class='t'>QUERY STRING</td><td class='d'> {0} </td></tr>", currentContext.Request.QueryString.ToString())
sb.AppendFormat("<tr><td class='t'>TARGET SITE</td><td class='d'> {0} </td></tr>", ex.TargetSite.Name)
sb.AppendFormat("<tr><td class='t'>STACK TRACE</td><td class='d'> {0} </td></tr>", ex.StackTrace)

sb.AppendFormat("<tr><td class='t'>USERID</td><td class='d'> {0} </td></tr>", userId)
sb.AppendFormat("<tr><td class='t'>USER</td><td class='d'> {0} </td></tr>", userName)
sb.Append("</table>")
sb.Append("</body>")
sb.Append("</html>")

更新

我得到了Steve的回答,他建议使用XML元素。我唯一需要做的就是通过在表达式中的每个大括号前面加上相同的大括号来逃避大括号。工作代码如下。

   Dim s As XElement = <html>
                            <head>
                                <style>
          body{{font-size:10pt; font-family:Arial, Sans Serif;}} 
           table{{margin:0; padding:0; border-collapse:collapse;}}
            td{{border:solid 1px #eee; padding:2px;}}
            .m{{color:#f00; font-weight:bold; font-size:14pt; margin-bottom:9px;}}
           .t{{width:120px; font-weight:bold; font-size:8pt;}}
           .d{{width:500px;}}
         </style>
                            </head>
                            <body>
                                <div class='m'>{0}</div>
                                <table>
                                    <tr><td class='t'>REQUEST URL</td><td class='d'>{1}</td></tr>
                                    <tr><td class='t'>REQUEST PATH</td><td class='d'>{2}</td></tr>"

<tr><td class='t'>QUERY STRING</td><td class='d'>{3}</td></tr>"
<tr><td class='t'>TARGET SITE</td><td class='d'>{4}</td></tr>
                                        <tr><td class='t'>STACK TRACE</td><td class='d'>{5}</td></tr>
                                        <tr><td class='t'>USERID</td><td class='d'>{6}</td></tr>
                                        <tr><td class='t'>USER</td><td class='d'>{7}</td></tr>
                                    </table>
                                </body>
                            </html>
        email.Body = sb.AppendFormat(s.ToString(), ex.Message.ToString(), _
                                 currentContext.Request.Url.OriginalString, _
                                 currentContext.Request.Path, _
                                 currentContext.Request.QueryString.ToString(), _
                                 ex.TargetSite.Name, ex.StackTrace, userId, userName).ToString()

性能更新

我尝试了这里讨论的所有3种方法,以找出哪种方法在我的方案中效果最好。因此,我使用这些方法中的每一种来运行ASP.Net方案(每个测试仅实现一种方法)

  • 测试1:具有StringBuiler.Format的XElement
  • 测试2:带有内联表达式的XElement
  • 测试3:具有我的问题中给出的代码的具有多个Appends和AppendFormat的StringBuilder

我使用秒表对象的滴答声发现的每次运行情况如下。对于每种方法,我都运行了4次ASP.Net方案。 StringBuilder的第三种方法似乎是最快的

  • 测试1:具有StringBuilder格式的XElement:6505、657、426、446
  • 测试2:具有内联表达式的XElement:6326、414、422、635
  • 测试3:StringBuilder附加/附加格式:6588、351,345、280

我认为当某人正在阅读/维护您的代码时,XElement可以提供更好的可读性,但是XElement的方法在性能上无法击败StringBuilder。

1 个答案:

答案 0 :(得分:4)

在这里用XML Literals编写代码。我尝试直接使用字符串,但是由于某种原因,结果被截断并且原始文本的某些部分丢失。但是使用XElement可以正常工作

Dim s As XElement = 
<html>  
    <head>  
        <style>  
            body {font-size:10pt; font-family:Arial, Sans Serif;} 
            table {margin:0; padding:0; border-collapse:collapse;} 
            td{border:solid 1px #eee; padding:2px;} 
            .m{color:#f00; font-weight:bold; font-size:14pt; margin-bottom:9px;}  
            .t{width:120px; font-weight:bold; font-size:8pt;} 
            .d{width:500px;} 
        </style> 
    </head> 
    <body> 
        <div class='m'><%= ex.Message %></div> 
        <table> 
            <tr> 
                <td class='t'>REQUEST URL</td> 
                <td class='d'><%= currentContext.Request.Url.OriginalString %></td> 
            </tr> 
            <tr> 
                <td class='t'>REQUEST PATH</td> 
                <td class='d'><%= currentContext.Request.Path %></td> 
            </tr> 
            <tr> 
                <td class='t'>QUERY STRING</td> 
                <td class='d'><%= currentContext.Request.QueryString.ToString() %></td> 
            </tr> 
            <tr> 
                <td class='t'>TARGET SITE</td> 
                <td class='d'><%= ex.TargetSite.Name %></td> 
            </tr> 
            <tr> 
                <td class='t'>STACK TRACE</td> 
                <td class='d'><%= ex.StackTrace %></td> 
            </tr> 
            <tr> 
                <td class='t'>USERID</td> 
                <td class='d'><%= userId %></td> 
            </tr> 
            <tr> 
                <td class='t'>USER</td> 
                <td class='d'><%= userName %></td> 
            </tr> 
        </table> 
    </body> 
</html> 

我们可以在样式块中的花括号周围使用双花括号,然后使用string.Format替换参数。 (部分代码摘自上面的代码)

....
body {{font-size:10pt; font-family:Arial, Sans Serif;}} 
....

这时我们可以使用String.Format来解析整个文本格式背后的代码

Dim text = String.Format(s.ToString(), ex.Message, .........)