如何在 C# 中自定义 WriteLine 的 String.Format 的早期评估中处理打印的大括号

How to handle printed curly braces in early evaluation of String.Format in a custom WriteLine in C#

我正在用 C# 编写 C# 代码生成器。但是,我 运行 遇到了打印初始化列表的问题。我已经将我的代码生成器简化为一个人为的例子。假设我想输出以下 class:

class Foo
{
  private static int[] m_bar = new[] {256};
}

下面是一个示例程序:

class Program
{
  private static int m_indentLevel;

  static void Main(string[] args)
  {
    var arrayDimension = 256;

    WriteLine("class Foo");
    WriteLine("{{");
    m_indentLevel++;

    // This works because the format string is passed all the way through to the 
    // Console.WriteLine
    string initializer = String.Format("new[] {{{0}}}", arrayDimension);
    WriteLine("private static int[] m_bar = {0};", initializer);

    // This doesn't work because the format string is evaluated before the Console.WriteLine.
    var intirim = String.Format("private static int[] m_bar = {0};", initializer);
    WriteLine(intirim);

    m_indentLevel--;
    WriteLine("}}");
  }

  private static void WriteLine(String format, params Object[] arg)
  {
    Console.WriteLine("{0}{1}", new String(' ', m_indentLevel * 2), String.Format(format, arg));
  }
}

此程序跟踪输出中的缩进并使用自定义 WriteLine 方法将给定字符串缩进到适当的级别。当我的自定义 WriteLine 的用户在给定格式字符串 中使用大括号(转义)调用我的 WriteLine 而不指定可选的 [=16] 时,我的问题就来了=],即他们在将格式字符串传递给我之前对其进行评估。

请注意,第一次尝试写入 private static int[] m_bar = new {256}; 成功,而第二次则抛出异常。

是否可以让我的 WriteLine 在这两种情况下都有效?我该怎么做?

intirim 将包含 "private static int[] m_bar = new {256}"。您将其传递给 String.Format,它将查找 arg[256]。由于您没有传递任何参数,因此它显然失败了。我可能会向 WriteLine 添加一个条件,例如:

string formatted = arg.Length > 0 ? String.Format(format, arg) : format;
Console.WriteLine("{0}{1}", new String(' ', m_indentLevel * 2), formatted);

但正如埃德所说,小心点,兔子洞又黑又深...

如果您希望 WriteLine()format 参数有两种不同的语义,具体取决于它后面是否有任何其他参数,我自己的偏好是为那种情况:

/// <summary>
/// Indent s and write to Console.Out without String.Format() interpolation
/// </summary>
public static void WriteLine(string s) { ... }

这是遵循 Console.WriteLine()String.Format() 的做法;两者都有相当多的重载。这在一定程度上是必要的,因为使用 paramsobject 的重载解析是棘手的、脆弱的东西。时刻警惕调用错误的过载。

也就是说,your design scares me。它让我想起了多年来我提出的 "quick and easy" 设计,我认为我可以使用某种语言功能为我完成大部分工作,但我很快发现自己在流沙中挣扎。您会免费得到一堆您想要的很酷的东西——但是您还会得到很多其他根本不适合您需要的东西。

这就像你在用章鱼把独木舟绑在你的车上。当然,它有所有那些漂亮的长长的触手,但它有自己的议程。在漫长的 运行 中,绳索可能需要您付出更少的努力和创造力,当一切都说完了。