Temporarily change a value (text color) and restore it after some operation (printing text)

Viewed 186

I want to make "a variable" that changes text color to green for whatever you print in its curly braces however when curly braces are closed it changes console text color back to gray for the next things I print.

So for short what I wanted to do is this:

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("test");
Console.ForegroundColor = ConsoleColor.gray;

but since I have this a lot in my code I want to short it like this:

mycmd(green, gray)
{
    Console.WriteLine("test");
}
2 Answers

You could do something like this

public static void ColorAndWrite(ConsoleColor c1, ConsoleColor c2, string text)
{
   Console.ForegroundColor = c1;
   Console.WriteLine(text);
   Console.ForegroundColor = c2;
}

usage

ColorAndWrite(ConsoleColor.Black,ConsoleColor.Blue, "asdads");

or use an Action

public static void ColorFancy(ConsoleColor c1, ConsoleColor c2, Action action)
{
   Console.ForegroundColor = c1;
   action.Invoke();
   Console.ForegroundColor = c2;
}

usage

ColorFancy(ConsoleColor.Black, ConsoleColor.Blue, () =>  Console.WriteLine("dfgdfgdfgdfg"));

// or

ColorFancy(ConsoleColor.Black, ConsoleColor.Blue, () =>
      {
         // lots of things here
         Console.WriteLine("dfgdfgdfgdfg");
      });

You can create an IDisposable implementation and abuse usings for that

public class ConsoleColorBlock : IDisposable
{
    private readonly ConsoleColor _c2;

    public ConsoleColorBlock(ConsoleColor c1, ConsoleColor c2)
    {
        Console.ForegroundColor = c1;
        _c2 = c2;
    }

    public void Dispose()
    {
        Console.ForegroundColor = _c2;
    }
}

And then in your code

using(new ConsoleColorBlock(ConsoleColor.Green, ConsoleColor.Gray))
{
    // Whatever code you want
}

Note that the code in the Dispose method will be executed even if the code inside the using throws an exception.

As suggested by @AlexeiLevenkov in the comments you can use this pattern to capture the current console color and restore it without explicitely passing it in the constructor.

public class ConsoleColorBlock : IDisposable
{
    private readonly ConsoleColor _originalColor;

    public ConsoleColorBlock(ConsoleColor color)
    {
        _originalColor = Console.ForegroundColor;
        Console.ForegroundColor = color;
    }

    public void Dispose()
    {
        Console.ForegroundColor = _originalColor;
    }
}
Related