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

Kev*_*lia 24 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Soc*_*cko 11

更新 - 原始字符串文字 - C#11 / .NET7 (2022 年 11 月)

通过在C#11中释放原始字符串文字,这将变得更容易处理

原始字符串文字是字符串文字的一种新格式。原始字符串文字可以包含任意文本,包括空格、换行符、嵌入引号和其他特殊字符,而无需转义序列。原始字符串文字以至少三个双引号 (""") 字符开头。它以相同数量的双引号字符结尾。

结束双引号左侧的任何空格都将从字符串文字中删除。

因此,以下三个示例创建相同的字符串:

public class Program
{
    public static void Main()
    {

        var message1 = 
@"First Line
Second Line";

        var message2 = 
            """
            First Line
            Second Line
            """;

        var message3 = """
                       First Line
                       Second Line
                       """;
    }
}
Run Code Online (Sandbox Code Playgroud)

.NET Fiddle / SharpLab中的演示

  • 似乎语言版本与 .NET 版本相关,因此 C# 11 是 .NET 7 - 供参考。https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version (3认同)
  • @aaaantoine,感谢修复并包含一个可运行的小提琴 (2认同)

Chr*_*air 9

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

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";

}
Run Code Online (Sandbox Code Playgroud)

使用方式如下:

stringLiteral = String.Format(MyStringResources.StringLiteral, var1, var2, var3);
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

stringLiteral = MyStringLiteralBuilder.Build(var1, var2, var3);
stringLiteral = MyStringLiteralBuilder.Build(var1, var2); //compiler error!
Run Code Online (Sandbox Code Playgroud)

当然,在这一点上,你可以用这些构建器做任何你想做的事情.为您的程序中的每个特殊大"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();
Run Code Online (Sandbox Code Playgroud)

  • 我只能希望在900岁的时候我会成为一名专业的风筝飞行员 (3认同)

Yeg*_*gor 6

就我而言,制作这样的扩展方法是可以接受的:

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))));
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明