在 Console.WriteLine 中调用 void 方法
Call a void method in Console.WriteLine
我正在开发一个 C# 控制台项目,但我对 C# 还是全新的。我的问题是:我可以在 Console.WriteLine();
中调用 void 方法吗?也许像
static void ChangeColor()
{
Console.backgroundColor = ConsoleColor.Red
};
Console.WriteLine("Hello *Calling method *ChangeColor();* * my friend!");
我的代码中的示例:
Console.Write(
$@"
____________________________________________________________________________________________________
| |
| __ __ |
| / / \__/\ \ |
| \/| /\/\|\/ |");
DarkBlueTxt();
Console.Write(
$@"
| __||o o||__ |
| / . \__/ . \ |
| /. .(__). . \ |
|______________________\ . /__\ . /_____________________________________________________________|");
您可以检查 ANSI 颜色,但它需要某种控制台模式,这在 link 中有说明。
static void Main(string[] args)
{
Console.WriteLine("\u001b[31mHello World!\u001b[0m");
}
来源:
Using ANSI colour codes in .NET Core Console applications
或许自己做一个辅助方法:
void WriteWithColors(params object[] p){
foreach(var o in p){
if(o is ConsoleColor)
Console.BackgroundColor = (ConsoleColor)o;
else
Console.Write(o);
}
}
然后这样称呼它:
WriteWithColors(ConsoleColor.Red, @"
____________________________________________________________________________________________________
| |
| __ __ |
| / / \__/\ \ |
| \/| /\/\|\/ |", ConsoleColor.Blue, @"
| __||o o||__ |
| / . \__/ . \ |
| /. .(__). . \ |
|______________________\ . /__\ . /_____________________________________________________________|");
编译器会将您的颜色和字符串组合捆绑到一个对象数组中,然后方法中的循环遍历它,根据它是什么(颜色或字符串)更改颜色或打印字符串
如果您不在字符串中使用 {placeholders},那么您不需要在字符串的头部加上 $ btw
只是为了好玩,您可以大量滥用新的 C# 10 Interpolated string handlers 让您编写例如:
WriteColoredText($"First{ConsoleColor.Red}Second");
请不要在实践中实际这样做 -- 这是一个可怕的 hack,没有人会理解。使用 :它可能更清晰,也更简单。但这是对新的内插字符串处理程序的强大功能的有趣探索。
说到这里,开始吧。
首先,我们需要定义我们自己的内插字符串处理程序,我们将包装 StringBuilder.AppendInterpolatedStringHandler
,因为这主要是我们想要的。然而,当 ConsoleColor
被写入时,我们将记录下来,以段列表结束,其中每个段是一段文本和写入它的颜色:
[InterpolatedStringHandler]
public struct ConsoleColorInterpolatedStringHander
{
private readonly StringBuilder sb = new();
private StringBuilder.AppendInterpolatedStringHandler appendHandler;
private ConsoleColor? currentColor = null;
public List<(ConsoleColor?, string)> Segments { get; } = new();
public ConsoleColorInterpolatedStringHander(int literalLength, int formattedCount)
{
appendHandler = new(literalLength, formattedCount, sb);
}
public void AppendLiteral(string value) => appendHandler.AppendLiteral(value);
public void AppendFormatted<T>(T value) => appendHandler.AppendFormatted(value);
public void AppendFormatted<T>(T value, string? format) => appendHandler.AppendFormatted(value, format);
public void AppendFormatted<T>(T value, int alignment) => appendHandler.AppendFormatted(value, alignment);
public void AppendFormatted<T>(T value, int alignment, string? format) => appendHandler.AppendFormatted(value, alignment, format);
public void AppendFormatted(ConsoleColor color)
{
Segments.Add((currentColor, sb.ToString()));
sb.Clear();
currentColor = color;
}
public void Finish()
{
Segments.Add((currentColor, sb.ToString()));
}
}
然后我们需要定义一个接受这个处理程序的方法:
public static void WriteColoredText(ConsoleColorInterpolatedStringHanderhandler)
{
handler.Finish();
foreach (var (color, text) in handler.Segments)
{
if (color != null)
{
Console.BackgroundColor = color.Value;
}
Console.Write(text);
}
}
然后我们可以将内插字符串传递给我们的新 WriteColoredText
方法。任何包含 ConsoleColor
的占位符都会导致背景颜色发生变化。
要了解发生了什么,请切换到 C# view on SharpLab。重要的一点是编译器已经将我们对 WriteColoredText
的调用写入:
public static void Main()
{
ConsoleColorInterpolatedStringHander handler = new ConsoleColorInterpolatedStringHander(10, 1);
handler.AppendLiteral("Hello");
handler.AppendFormatted(ConsoleColor.Red);
handler.AppendLiteral("World");
WriteColoredText(handler);
}
的变体:
void WriteWithColors(params (ConsoleColor? Color, string Text)[] colorizedTextCollection)
{
foreach (var colorizedText in colorizedTextCollection)
{
Console.BackgroundColor = colorizedText.Color ?? Console.BackgroundColor;
Console.Write(colorizedText.Text);
}
}
- 这里您可以传递颜色和文本元组,而不是接收
objec
t 数组
- 通过这种方法,
foreach
的主体变得更简单了
示例用法:
WriteWithColors((ConsoleColor.Red, "red"),
(null, "still red"),
(ConsoleColor.DarkBlue, "blue"));
谢谢大家!你们都有很好的答案。为了简单起见,我现在将绘图的每个不同颜色的部分放在不同的方法中,然后一个一个地调用部分和颜色方法,这是我认为最简单的方法,即使我不想这样做像那样但不幸的是我想要的似乎不存在。再次感谢您的回答!
我正在开发一个 C# 控制台项目,但我对 C# 还是全新的。我的问题是:我可以在 Console.WriteLine();
中调用 void 方法吗?也许像
static void ChangeColor()
{
Console.backgroundColor = ConsoleColor.Red
};
Console.WriteLine("Hello *Calling method *ChangeColor();* * my friend!");
我的代码中的示例:
Console.Write(
$@"
____________________________________________________________________________________________________
| |
| __ __ |
| / / \__/\ \ |
| \/| /\/\|\/ |");
DarkBlueTxt();
Console.Write(
$@"
| __||o o||__ |
| / . \__/ . \ |
| /. .(__). . \ |
|______________________\ . /__\ . /_____________________________________________________________|");
您可以检查 ANSI 颜色,但它需要某种控制台模式,这在 link 中有说明。
static void Main(string[] args)
{
Console.WriteLine("\u001b[31mHello World!\u001b[0m");
}
来源: Using ANSI colour codes in .NET Core Console applications
或许自己做一个辅助方法:
void WriteWithColors(params object[] p){
foreach(var o in p){
if(o is ConsoleColor)
Console.BackgroundColor = (ConsoleColor)o;
else
Console.Write(o);
}
}
然后这样称呼它:
WriteWithColors(ConsoleColor.Red, @"
____________________________________________________________________________________________________
| |
| __ __ |
| / / \__/\ \ |
| \/| /\/\|\/ |", ConsoleColor.Blue, @"
| __||o o||__ |
| / . \__/ . \ |
| /. .(__). . \ |
|______________________\ . /__\ . /_____________________________________________________________|");
编译器会将您的颜色和字符串组合捆绑到一个对象数组中,然后方法中的循环遍历它,根据它是什么(颜色或字符串)更改颜色或打印字符串
如果您不在字符串中使用 {placeholders},那么您不需要在字符串的头部加上 $ btw
只是为了好玩,您可以大量滥用新的 C# 10 Interpolated string handlers 让您编写例如:
WriteColoredText($"First{ConsoleColor.Red}Second");
请不要在实践中实际这样做 -- 这是一个可怕的 hack,没有人会理解。使用
说到这里,开始吧。
首先,我们需要定义我们自己的内插字符串处理程序,我们将包装 StringBuilder.AppendInterpolatedStringHandler
,因为这主要是我们想要的。然而,当 ConsoleColor
被写入时,我们将记录下来,以段列表结束,其中每个段是一段文本和写入它的颜色:
[InterpolatedStringHandler]
public struct ConsoleColorInterpolatedStringHander
{
private readonly StringBuilder sb = new();
private StringBuilder.AppendInterpolatedStringHandler appendHandler;
private ConsoleColor? currentColor = null;
public List<(ConsoleColor?, string)> Segments { get; } = new();
public ConsoleColorInterpolatedStringHander(int literalLength, int formattedCount)
{
appendHandler = new(literalLength, formattedCount, sb);
}
public void AppendLiteral(string value) => appendHandler.AppendLiteral(value);
public void AppendFormatted<T>(T value) => appendHandler.AppendFormatted(value);
public void AppendFormatted<T>(T value, string? format) => appendHandler.AppendFormatted(value, format);
public void AppendFormatted<T>(T value, int alignment) => appendHandler.AppendFormatted(value, alignment);
public void AppendFormatted<T>(T value, int alignment, string? format) => appendHandler.AppendFormatted(value, alignment, format);
public void AppendFormatted(ConsoleColor color)
{
Segments.Add((currentColor, sb.ToString()));
sb.Clear();
currentColor = color;
}
public void Finish()
{
Segments.Add((currentColor, sb.ToString()));
}
}
然后我们需要定义一个接受这个处理程序的方法:
public static void WriteColoredText(ConsoleColorInterpolatedStringHanderhandler)
{
handler.Finish();
foreach (var (color, text) in handler.Segments)
{
if (color != null)
{
Console.BackgroundColor = color.Value;
}
Console.Write(text);
}
}
然后我们可以将内插字符串传递给我们的新 WriteColoredText
方法。任何包含 ConsoleColor
的占位符都会导致背景颜色发生变化。
要了解发生了什么,请切换到 C# view on SharpLab。重要的一点是编译器已经将我们对 WriteColoredText
的调用写入:
public static void Main()
{
ConsoleColorInterpolatedStringHander handler = new ConsoleColorInterpolatedStringHander(10, 1);
handler.AppendLiteral("Hello");
handler.AppendFormatted(ConsoleColor.Red);
handler.AppendLiteral("World");
WriteColoredText(handler);
}
void WriteWithColors(params (ConsoleColor? Color, string Text)[] colorizedTextCollection)
{
foreach (var colorizedText in colorizedTextCollection)
{
Console.BackgroundColor = colorizedText.Color ?? Console.BackgroundColor;
Console.Write(colorizedText.Text);
}
}
- 这里您可以传递颜色和文本元组,而不是接收
objec
t 数组 - 通过这种方法,
foreach
的主体变得更简单了
示例用法:
WriteWithColors((ConsoleColor.Red, "red"),
(null, "still red"),
(ConsoleColor.DarkBlue, "blue"));
谢谢大家!你们都有很好的答案。为了简单起见,我现在将绘图的每个不同颜色的部分放在不同的方法中,然后一个一个地调用部分和颜色方法,这是我认为最简单的方法,即使我不想这样做像那样但不幸的是我想要的似乎不存在。再次感谢您的回答!