静态字符串的链式插值无法正常工作

时间:2020-01-17 09:43:38

标签: c# string string-interpolation

我使用的是这样的代码:

public static class Program {
    public static void Main() {
        Console.WriteLine(hello);
    }

    internal static readonly string hello = $"hola {name} {num}";
    internal static readonly string name  = $"Juan {num}";
    public const int num = 4;
}

在这种情况下,当我得到hello的值时,它会返回给我“ hola 4”,因此在插值另一个使用插值的字符串时似乎出现了问题。 我的预期行为是“ hola Juan 4 4”,或者如果该语言不支持这种链式插值,则会在编译时出错。

有人知道为什么C#会得到这种行为吗?

2 个答案:

答案 0 :(得分:7)

静态字段按照声明的顺序初始化。那么发生的是:

  1. 最初,helloname均为nullnum是常量。
  2. hello已初始化。 name仍为null。但是,num是一个const,因此可以正确替换。 hello的值为"hola 4"
  3. name已初始化。

为什么num是const会有所不同?请记住,编译器在编译时会将const的值直接替换为它使用的位置。因此,如果您查看编译器生成的内容,则会看到:

public static class Program
{
    internal static readonly string hello = string.Format("hola {0} {1}", name, 4);

    internal static readonly string name = string.Format("Juan {0}", 4);

    public const int num = 4;

    public static void Main()
    {
        Console.WriteLine(hello);
    }
}

(由SharpLab提供)

注意const的值如何编译到使用的位置。


当您具有相互依赖的静态字段时,您要么需要非常小心地声明它们的顺序,要么通常更安全(并且更具可读性!)只使用静态构造函数即可:

public static class Program {
    static Program() {
        name = $"Juan {num}";
        hello = $"hola {name} {num}";
    }

    public static void Main() {
        Console.WriteLine(hello);
    }

    internal static readonly string hello;
    internal static readonly string name;
    public const int num = 4;
}

答案 1 :(得分:1)

您可以像这样切换helloname的位置,

internal static readonly string name = $"Juan {num}";
internal static readonly string hello = $"hola {name} {num}";

因为正在分配hello,所以尚未分配name

重新排序namehello后,它将根据需要打印

印刷=>“霍拉·胡安4 4”