32

Recently, I faced the below question in an interview. Initially I thought that the question was wrong, but the interviewer mentioned there is a solution for this. Given this class:

public class BaseHome
{
    public static void Main()
    {
        Console.WriteLine("A");
    }
}

Write the following to the console:

B
A
C

Rules:

  1. Do not change the Main function.
  2. Do not create any additional classes.

How can this be done?

nobody
  • 19,814
  • 17
  • 56
  • 77
user3714387
  • 353
  • 3
  • 3

5 Answers5

49

Assuming you meant B A C on three lines (plus no typo on main method name):

namespace ConsoleApplication1
{
    public class BaseHome
    {
        static BaseHome()
        {
            Console.WriteLine("B");

            AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
        }

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

        private static void OnProcessExit(object sender, EventArgs e)
        {
            Console.WriteLine("C");
            Console.Read();
        }
    }
}
ken2k
  • 48,145
  • 10
  • 116
  • 176
25

Hahaha, I figured it out. Create a static property!

public class BaseHome
{
    public static void Main()
    {
       Console.WriteLine("A");
    }

    public static BaseHome Console
    {
        get{ return new BaseHome(); }
    }

    public void WriteLine(string s) {
        System.Console.WriteLine("BCA"); //Or multiple lines if you like
    }

}

Edit: Or, duh, just a field

public class BaseHome
{
    static BaseHome Console = new BaseHome();

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

    public void WriteLine(string s) {
        System.Console.WriteLine("BCA"); //Or multiple lines if you like
    }

}
Dennis_E
  • 8,751
  • 23
  • 29
  • 1
    That's pretty neat imo. – AndreySarafanov Jun 06 '14 at 09:56
  • 4
    Clever answer. I like this because it indicates that you pay attention to details. The `BaseHome` console program/class could _easily_ be `static` (and, at least in my experience, it usually is static, or at least not treated like an instantiable class). This takes advantage of that detail and wouldn't work otherwise. – Chris Sinclair Jun 06 '14 at 10:40
  • 1
    If the class were static, you can make a property that returns an anonymous type, but I don't know if that violates the do-not-create-a-class constraint: public static dynamic Console { get { Action WriteLine = s => System.Console.WriteLine("BCA"); return new { WriteLine }; } } – Dennis_E Jun 06 '14 at 11:20
  • 1
    @Dennis_E: Good thinking. If anonymous types aren't allowed (which seems quite plausible) you can use an [`ExpandoObject`](http://msdn.microsoft.com/en-ca/library/system.dynamic.expandoobject.aspx) instead! – Chris Sinclair Jun 06 '14 at 16:25
  • This is why C# is my favorite language; so many beautiful features! – Dennis_E Jun 06 '14 at 16:48
  • Wow, that's a good one! – matiash Jun 11 '14 at 01:41
17

No new types. No objects explicitly created. Works in a real Console application.

public class BaseHome
{
    static System.IO.TextWriter Console
    {
        get
        {
            System.Console.Write("  C\rB");
            return System.Console.Out;
        }
    }
    public static void Main()
    {
        Console.WriteLine("A");
        // System.Console.ReadLine();
    }
}

Result is BAC - on the same line no less!

(This can be adapted to multiple line output, per the post edit, with the use of CurstorLeft/Top or direct escape sequences.)


Explanation:

The static property (Console) is resolved instead of the type in Console.WriteLine("A") as the property shadows the type here; this is why System.Console is used to refer to the Console class itself.

The Console get-property causes a side-effect of writing to the console - it writes "__C" then uses CR (Carriage Return) to "return to the line start" and writes "B" so the line is "B_C", leaving the cursor after the "B".

The property then returns the TextWriter associated with the console which has WriteLine. The TextWriter's WriteLine, not Console's static WriteLine, is then invoked and the character "A" is written (after "B") so the result is "BAC".

This utilizes context-specific behavior because it is the console which understands how to move the cursor (e.g. with "\r" or other cursor positioning).

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
13

Just a static constructor is needed:

public class BaseHome
{
    static BaseHome()
    {
        Console.WriteLine("B\nA\nC");
        Console.SetOut(System.IO.TextWriter.Null);
    }

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

Instead of redirecting the output stream, other options include calling Environment.Exit, throwing an unhandled exception, or just spinning forever. It is unclear if the program is required to terminate normally (or at all).

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
5
struct ConsoleStruct
{
    private string _text;
    public ConsoleStruct(string text)
    {
        _text = text;
    }

    public void WriteLine(string txt)
    {
        Console.WriteLine(_text);
    }
}
class Program
{
    private static ConsoleStruct Console = new ConsoleStruct("B A C");
    static void Main(string[] args)
    {
        Console.WriteLine("A");
    }
}
AndreySarafanov
  • 804
  • 5
  • 20