使用使用空格的字符串文字保持代码结构

时间:2013-06-25 21:23:30

标签: c# indentation string-literals

所以有点奇怪的问题我无法提出搜索条件。如果我的程序中有多行字符串文字,那么无论如何都要保持代码缩进的一致性,而不会在字符串文字中添加不需要的空格?

例如:

if (true)
{
    if (!false)
    {
        //Some indented code;
        stringLiteral = string.format(
@"This is a really long string literal
I don't want it to have whitespace at 
the beginning of each line, so I have
to break the indentation of my program
I also have vars here 
{0}
{1}
{2}",
var1, var2, var3);
    }
}

这可能只是我的OCD说话,但无论如何都要保持我的程序缩进而不向字符串添加不需要的空格,或者必须逐行构建它(真正的字符串是超长字符串。格式是20~行内有12个变量)?

8 个答案:

答案 0 :(得分:8)

我会将它完全抽象为一个单独的静态类或资源:

public static class MyStringResources
{
    public static readonly string StringLiteral = 
@"This {0} a really long string literal
I don't want {1} to have {2} at 
the beginning of each line, so I have
to break the indentation  of my program";

}

使用方式如下:

stringLiteral = String.Format(MyStringResources.StringLiteral, var1, var2, var3);

更好的是,通过这种方式你可以拥有一个很好的功能需要预期变量的数量:

public static class MyStringLiteralBuilder
{
    private static readonly string StringLiteral = 
@"This {0} a really long string literal
I don't want {1} to have {2} at 
the beginning of each line, so I have
to break the indentation  of my program";

    public static string Build(object var1, object var2, object var3)
    {
        return String.Format(MyStringResources.StringLiteral, var1, var2, var3);
    }
}

然后你不能意外地错过变量(甚至可能强烈地将它们输入数字,布尔等)。

stringLiteral = MyStringLiteralBuilder.Build(var1, var2, var3);
stringLiteral = MyStringLiteralBuilder.Build(var1, var2); //compiler error!

当然,在这一点上,您可以使用这些构建器做任何您想做的事情。为您的程序中的每个特殊大“stringLiteral”创建一个新的构建器。也许不是让他们static他们可以是你可以获得/设置关键属性的实例,那么你也可以给他们好名字:

public class InfoCardSummary
{
    public string Name { get; set; }
    public double Age { get; set; }
    public string Occupation { get; set; }

    private static readonly string FormattingString = 
@"This person named {0} is a pretty
sweet programmer. Even though they're only
{1}, Acme company is thinking of hiring
them as a {2}.";

    public string Output()
    {
        return String.Format(FormattingString, Name, Age, Occupation);
    }
}

var info = new InfoCardSummary { Name = "Kevin DiTraglia", Age = 900, Occupation = "Professional Kite Flier" };
output = info.Output();

答案 1 :(得分:3)

在另一个文件中定义字符串常量,并在代码中使用该标识符。如果您需要翻译,审查合规性等,最好将所有字符串放在一个地方。

答案 2 :(得分:2)

if (true)
{
    if (!false)
    {
        //Some indented code;
        stringLiteral = string.format(
                    "This is a really long string literal. " +
                    "I don't want it to have whitespace at " +
                    "the beginning of each line, so I have " +
                    "to break the indentation of my program " +
                    "I also have vars here: " +
                    "{0} " +
                    "{1} " +
                    "{2}",
                  var1, var2, var3);
          // OR, with lineskips:
        stringLiteral = string.format(
                    "This is a really long string literal\r\n" +
                    "I don't want it to have whitespace at \r\n" +
                    "the beginning of each line, so I have\r\n" +
                    "to break the indentation of my program\r\n"
                    "I also have vars here\r\n" +
                    "{0}\r\n" +
                    "{1}\r\n" +
                    "{2}\r\n",
                  var1, var2, var3);
    }
}

不漂亮但有效。

答案 3 :(得分:1)

C#语言的语法允许两种指定字符串文字的方法:

  • here-doc / at-string(@"..."),可能跨越源文件行,或
  • ordindary字符串文字("..."),可能不是。

获得所需效果的其他方法:

  1. 将字符串放入资源文件中。这使本地化变得更容易。

  2. 将它们作为嵌入(文件)资源添加到程序集中:

  3. 另一种选择,在尝试其他答案的过程中,让它看起来更漂亮:

    static readonly string MultilineLiteral = string.Join( Environment.NewLine , new string[]{
                                              @"line 1" ,
                                               "line 2" ,
                                              @"line 3" ,
                                              . . .
                                              "line n" ,
                                              }) ;
    

答案 4 :(得分:0)

当组合@verbatim字符串和更新的$ string插值时,您可以应用以下技巧:在{和}内,它是一个表达式(因此代码)而不是字符串数据。把你的换行符和缩进放在那里,它不会出现在格式化的字符串中。如果您的文本不包含表达式,则必须使用空表达式。我试过{}但不幸的是这不起作用:表达式预期错误。作为最小使用{nl},将空字符串分配给nl。换行符nl,或{换行}或类似的东西。

using System;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 123;
            string nl = string.Empty;
            Console.WriteLine($@"Abc {count} def {count
                } ghi {
                count} jkl{nl
                } mno");
            Console.ReadLine();
        }
    }
}

输出:

Abc 123 def 123 ghi 123 jkl mno

答案 5 :(得分:0)

在我的情况下,可以使用这样的扩展方法:

class Program
{
    static void Main(string[] args)
    {
        var code = $@"
            public static loremIpsum(): lorem {{
                return {{
                    lorem: function() {{
                        return 'foo'
                    }},
                    ipsum: function() {{
                        return 'bar'
                    }},
                    dolor: function() {{
                        return 'buzz'
                    }}
                }}
            }}".AutoTrim();

        Console.WriteLine(code);
    }
}

static class Extensions
{
    public static string AutoTrim(this string code)
    {
        string newline = Environment.NewLine;
        var trimLen = code
            .Split(newline)
            .Skip(1)
            .Min(s => s.Length - s.TrimStart().Length);

        return string.Join(newline,
            code
            .Split(newline)
            .Select(line => line.Substring(Math.Min(line.Length, trimLen))));
    }
}

enter image description here

答案 6 :(得分:0)

另一种“解决方案”是将每个这样的字符串包装在#region中并将其折叠。这并不能真正解决问题,但至少可以使代码不那么麻烦。

答案 7 :(得分:-2)

我也遇到过这个问题。

有时我将整个事情放在\n(或\r\n用于dos / windows)的一行上。

有时候,我只是忽略了丑陋的代码格式化。

其他时候,我将文本放在别处 - 我认为在c#中你有#define,或者甚至在一个单独的文件或数据库中,这取决于所讨论的字符串。你仍然需要替换变量 - 在c#中我认为你使用string.Format?

我希望这足以让你开始解决问题。