如何在 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()
的做法;两者都有相当多的重载。这在一定程度上是必要的,因为使用 params
和 object
的重载解析是棘手的、脆弱的东西。时刻警惕调用错误的过载。
也就是说,your design scares me。它让我想起了多年来我提出的 "quick and easy" 设计,我认为我可以使用某种语言功能为我完成大部分工作,但我很快发现自己在流沙中挣扎。您会免费得到一堆您想要的很酷的东西——但是您还会得到很多其他根本不适合您需要的东西。
这就像你在用章鱼把独木舟绑在你的车上。当然,它有所有那些漂亮的长长的触手,但它有自己的议程。在漫长的 运行 中,绳索可能需要您付出更少的努力和创造力,当一切都说完了。
我正在用 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()
的做法;两者都有相当多的重载。这在一定程度上是必要的,因为使用 params
和 object
的重载解析是棘手的、脆弱的东西。时刻警惕调用错误的过载。
也就是说,your design scares me。它让我想起了多年来我提出的 "quick and easy" 设计,我认为我可以使用某种语言功能为我完成大部分工作,但我很快发现自己在流沙中挣扎。您会免费得到一堆您想要的很酷的东西——但是您还会得到很多其他根本不适合您需要的东西。
这就像你在用章鱼把独木舟绑在你的车上。当然,它有所有那些漂亮的长长的触手,但它有自己的议程。在漫长的 运行 中,绳索可能需要您付出更少的努力和创造力,当一切都说完了。