【问题标题】:Interesting OOPS puzzle [closed]有趣的 OOPS 谜题[关闭]
【发布时间】:2014-07-27 12:03:46
【问题描述】:

最近,我在一次采访中遇到了以下问题。最初我认为这个问题是错误的,但面试官提到有一个解决方案。给定这个类:

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

将以下内容写入控制台:

B
A
C

规则:

  1. 不要更改 Main 函数。
  2. 不要创建任何其他类。

如何做到这一点?

【问题讨论】:

  • @ken2k 我也看到了。所以解决方案可能是只创建一个 Main 方法
  • 不允许在键盘上输入任何内容或移动鼠标
  • 由于这不是一个程序,我假设 B 和 C 是从调用 BaseHome.main 来提供 A 的程序中输出的
  • 这确实是 CodeGolf.SE 的问题。
  • 同意,这个问题更适合CodeGolf

标签: c# oop puzzle


【解决方案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();
        }
    }
}

【讨论】:

  • 是的,我认为这是解决方案。我在考虑计时器,但这是更好的解决方案
  • +1 干得好。这可以根据需要工作。
  • +1 太棒了。我什至无法想到 ProcessExit!
  • 这个静态 BaseHome() 方法是什么?这是构造函数吗?
  • @bodycountPP 参考。 Static Constructors: "静态构造函数用于初始化任何静态数据,或执行只需要执行一次的特定操作。它在创建第一个实例或引用任何静态成员之前自动调用。"跨度>
【解决方案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
    }

}

编辑:或者,呃,只是一个字段

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
    }

}

【讨论】:

  • 这很漂亮。
  • 聪明的答案。我喜欢这个,因为它表明你关注细节。 BaseHome 控制台程序/类可以轻松地 成为static(并且,至少根据我的经验,它通常是静态的,或者至少不被视为可实例化的类)。这利用了该细节,否则将无法正常工作。
  • 如果类是静态的,你可以创建一个返回匿名类型的属性,但我不知道这是否违反了 do-not-create-a-class 约束:public static dynamic Console { get { Action WriteLine = s => System.Console.WriteLine("BCA");返回新的 { WriteLine }; } }
  • @Dennis_E:好主意。如果不允许匿名类型(这似乎很合理),您可以使用 ExpandoObject 代替!
  • 这就是为什么 C# 是我最喜欢的语言;这么多漂亮的功能!
【解决方案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 或直接转义序列。)


解释:

静态属性(Console)被解析,而不是Console.WriteLine("A")中的类型作为属性阴影这里的类型;这就是为什么使用 System.Console 来引用 Console 类本身的原因。

控制台获取属性会导致写入控制台的副作用 - 它写入“__C”,然后使用 CR(回车)“返回到行开头”并写入“B”,因此该行是“B_C ",将光标留在“B”之后。

然后该属性返回具有 WriteLine 的TextWriter associated with the console。然后调用TextWriter's WriteLine,而不是控制台的静态 WriteLine,并写入字符“A”(在“B”之后),因此结果为“BAC”。

这利用了特定于上下文的行为,因为它是understands how to move the cursor 的控制台(例如,带有“\r”或其他光标定位)。

【讨论】:

  • 这很聪明!
  • 这很狡猾。您也可以在静态构造函数中重定向控制台的输出流。看我的回答。
  • 说明,我要一个!
  • @bodycountPP 许愿。
【解决方案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");
    }
}

【讨论】:

  • 只需让结构中的 WriteLine 接受它忽略的参数即可轻松修复。
  • @JanneMatikainen 是的,已修复。仍然比 ken2k 更糟糕的解决方案
  • 不应该创建任何额外的类暗示在这种情况下没有结构太恕我直言
猜你喜欢
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 2011-10-01
  • 1970-01-01
  • 2013-11-17
  • 2019-06-17
  • 1970-01-01
相关资源
最近更新 更多