C#是主要问题


10

这个编程难题的灵感来自于昨天在这里提出但又被作者删除的另一个问题。

挑战:

使用Visual C#(或您喜欢的C#IDE)创建可执行二进制文件(Windows .EXE或Linux二进制文件),该文件将以下文本打印到标准输出中:

Main() is the main method of C# programs!

...而不使用任何源文件中出现的4个连续字母MAIN!

笔记:

  • 如果您的源代码包含文本remainder(例如),则它包含4个连续的字母MAIN,但是如果包含4个字母,则mxain不再是连续的,因此mxain将被允许​​。
  • 除了C#IDE之外,您不能运行任何程序,也不能更改C#IDE的设置来运行其他程序(但可以正常运行的程序,例如C#编译器)。

    否则,您可以简单地说:“我使用C#IDE编写Pascal程序,并在C#项目的“预构建”步骤中调用Pascal编译器。

    这太简单了。

  • 可以使用“插件”(或类似插件)进行扩展的IDE用户,或具有内置二进制文件编辑器(十六进制编辑器)的用户,将比其他C#IDE的用户拥有太大的优势。

    因此,也不应使用这些功能。

  • 明确允许使用其他非ASCII编辑器(例如对话框窗口编辑器)!
  • 用户使用函数名称中的反斜杠提出这样的原始问题,就像这样:static void M\u0061in()由于其他用户已经阅读了此答案,因此将不再接受该答案!
  • 用户询问是否允许将.EXE文件简单地输入到源代码编辑器中,并将文件另存为“ .exe”而不是“ .cs”。答:我认为这不可能,因为有效的Windows和Linux二进制文件都包含NUL字节。但是,如果找到可以通过这种方式创建的有效二进制文件,则您将获得有效的解决方案。

该站点的名称是“ Programming Puzzles Code Golf”-这是“ Programming Puzzles Code Golf”,而不是“ Code Golf”:挑战是要在所有其他用户之前找到可行的解决方案,而不是找到比所有其他用户都短的解决方案解决方案。

因此,描述有效解决方案第一篇文章胜出

祝好运!

顺便说一句:我有一个在Visual C#Express 2010下工作的解决方案。


2
是什么让我无法使用C#IDE作为文本(或二进制)编辑器直接键入可执行文件?
feersum '16

2
哪个答案胜过挑战?第一个有效答案?您应该指定获胜条件
James

如果IDE包含十六进制编辑器或类似的编辑器,则不允许这样做。如果您设法使用ASCII文本编辑器键入有效的二进制文件,则将允许这样做。请注意,有效的二进制文件包含0x00到0x1F范围内的字节!
Martin Rosenau

2
我认为这总体上是一个有趣的挑战。“编写没有main的C#程序”。但是,大多数规则都与使用哪些工具/ IDE有关,并禁止使用某些方法。我希望看到更多的编程难题(与代码高尔夫球相反),但这一难题并未得到充分说明。我建议下次使用沙箱
詹姆斯,

4
... 下次考虑沙盒
2016年

Answers:


5

C#互动式视窗

打开C#交互式窗口(在Visual Studio 2015中为“视图”>“其他Windows”>“ C#交互式”)。我想并不是所有的IDE都会有这个。

这种方法在“交互窗口”中执行C#,以创建一个C#exe,该exe无需编写者就可以打印出所需的字符串main。另外,exe的IL也不含main

在交互式窗口中运行以下代码

using System.Reflection;
using System.Reflection.Emit;
var appMeow = (dynamic)System.Type.GetType("System.AppDom" + "ain").GetProperty("CurrentDom" + "ain", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public).GetValue(null);
var asmName = new AssemblyName("MEOW");
var asmBuilder = appMeow.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var module = asmBuilder.DefineDynamicModule("MEOW", "MEOW.exe");
var typeBuilder = module.DefineType("Meow", TypeAttributes.Public);
var entryPoint = typeBuilder.DefineMethod("EntryPoint", MethodAttributes.Static | MethodAttributes.Public);
var il = entryPoint.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Meow() is the meow method of C# programs!");
il.Emit(OpCodes.Ldstr, "eow");
il.Emit(OpCodes.Ldstr, "ain");
il.EmitCall(OpCodes.Call, typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) }), null);
il.EmitCall(OpCodes.Call, typeof(Console).GetMethod("Write", new[] { typeof(string) }), null);
il.Emit(OpCodes.Ret);
var type = typeBuilder.CreateType();
asmBuilder.SetEntryPoint(type.GetMethods()[0]);
asmBuilder.Save("MEOW.exe");

Environmnent.CurrentDirectory看的exe创建哪里。运行它以观察所需的输出。

在此处输入图片说明

产生的IL: 在此处输入图片说明


实际上,我比WPF更好,因为您实际上在程序集中没有Main()。
hstde

您的解决方案很有趣。这是第二篇,因此如果用户说服我第一篇文章不是有效的解决方案(无论出于何种原因),您将赢得胜利。
马丁·罗瑟瑙

如果您问我,哪个职位获胜并不重要,因为他们都是同一位用户。
hstde

@hstde-对不起,我没有看到这个。谢谢。
马丁·罗斯瑙

@milk您发布了两个有效的解决方案(嗯,有些用户对第一个解决方案有疑问),所以您赢了。恭喜你
马丁·罗瑟瑙

3

WPF应用

  1. 创建一个新的WPF应用程序。 在此处输入图片说明

  2. 替换的所有实例MainMeow 在此处输入图片说明

  3. 重命名MainWindow.xamlMeowWindow.xaml。这将自动重命名MainWindow.xaml.csMeowWindow.xaml.cs

在此处输入图片说明

  1. 在项目属性中,将“输出”类型更改为,Console Application以便创建控制台。 在此处输入图片说明

  2. MeowWindow构造函数中 为所需的输出字符串添加控制台写入在此处输入图片说明

  3. Ctrl + Shift + F确认main源目录中没有任何内容。 在此处输入图片说明

  4. F5 /编译并运行。 在此处输入图片说明

怎么运行的

对于WPF应用程序,Visual Studio生成obj\Debug\App.g.cs包含该Main方法的对象。生成的将Main创建您的WPF应用的实例并启动它。


有趣的解决方案。任何人认为这不是有效的解决方案?如果有人认为此帖子无效,请发表评论。否则,我将宣布此解决方案为获奖方案,因为它显然是第一个发布的方案。
马丁·罗斯瑙

@MartinRosenau我认为,由于您可以反编译wpf应用程序,因此会有一种主要方法,该方法无效,更重要的是,因为同一用户发布了另一个没有这种歧义的答案

我刚刚看到两个答案都是由同一用户发布的。在这种情况下,该用户仍然会赢。
马丁·罗瑟瑙

0

仅供参考

我的想法类似于“牛奶”的第二个想法:

寻找一种方法让IDE执行代码并将可执行文件写入磁盘。

我明确提到Windows和Linux二进制文件是因为我考虑过使用编写二进制.EXE文件,System.IO.File.WriteAllBytes()因此它不一定是.NET EXE文件。

我的问题是VS Express 2010似乎没有交互式控制台,因此我不得不寻找一个替代品-我发现以下内容:

创建一个带有对话框窗口和自定义控件的DLL项目;编译项目并将自定义控件添加到对话框窗口。然后,对话框窗口编辑器将调用自定义控件的代码-在此代码中,您可以将.EXE文件写入磁盘...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.