Интересная головоломка OOPS
В последнее время я столкнулся с таким вопросом в интервью. Первоначально я думал, что вопрос был неправильным, но интервьюер отметил, что для этого есть решение. Учитывая этот класс:
public class BaseHome
{
public static void Main()
{
Console.WriteLine("A");
}
}
Напишите на консоль следующее:
B
A
C
Правила:
- Не меняйте основную функцию.
- Не создавайте дополнительных классов.
Как это можно сделать?
Ответы
Ответ 1
Предполагая, что вы имели в виду B A C на трех строках (плюс нет опечатки на имени метода main
):
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();
}
}
}
Ответ 2
Ха-ха-ха, я понял это. Создайте статическое свойство!
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
}
}
Изменить: Или, duh, просто поле
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
}
}
Ответ 3
Нет новых типов. Объекты явно не созданы. Работает в реальном консольном приложении.
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();
}
}
Результат BAC
- в той же строке не менее!
(Это может быть адаптировано к нескольким выводам строки для редактирования после публикации с использованием CurstorLeft/Top или прямых escape-последовательностей. )
Пояснение:
Статическое свойство (Console
) разрешено вместо типа в Console.WriteLine("A")
, так как свойство теневое имя здесь; поэтому System.Console используется для обозначения самого класса консоли.
Консоль get-property вызывает побочный эффект записи на консоль - он пишет "__C", затем использует CR (возврат каретки) для "возврата к началу строки" и пишет "B", поэтому строка "B_C", оставив курсор после "B".
Затем свойство возвращает TextWriter, связанный с консолью, который имеет WriteLine. Затем вызывается TextWriter WriteLine, а не консольная статическая WriteLine, и символ "A" записывается (после "B" ), поэтому результат "БАК".
Это использует контекстно-зависимое поведение, потому что это консоль, которая понимает, как перемещать курсор (например, с помощью "\r" или другого позиционирования курсора).
Ответ 4
Требуется только статический конструктор:
public class BaseHome
{
static BaseHome()
{
Console.WriteLine("B\nA\nC");
Console.SetOut(System.IO.TextWriter.Null);
}
public static void Main()
{
Console.WriteLine("A");
}
}
Вместо перенаправления выходного потока другие параметры включают вызов Environment.Exit
, бросание необработанного исключения или просто вращение навсегда. Неясно, требуется ли вообще нормальная работа (или вообще) программы.
Ответ 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");
}
}