C # - главная проблема

10

Эта программная головоломка вдохновлена ​​другим вопросом, который был задан здесь вчера, но который был удален автором ...

Соревнование:

Создайте исполняемый двоичный файл (двоичный файл Windows .EXE или Linux) с помощью Visual C # (или вашей любимой C # IDE), который выводит следующий текст в стандартный вывод:

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

... без использования 4 последовательных букв MAIN, появляющихся в любом исходном файле!

Ноты:

  • Если ваш исходный код содержит текст remainder(например), он содержит 4 последовательных буквы MAIN, однако, если он содержит mxain4 буквы, они больше не будут последовательными, поэтому mxainэто будет разрешено.
  • Вам не разрешается запускать какие-либо программы, кроме C # IDE, а также не изменять настройки C # IDE для запуска других программ (кроме тех, которые он обычно запускает, таких как компилятор C #).

    В противном случае вы можете просто сказать: «Я пишу программу на Pascal, используя C # IDE, и вызываю компилятор Pascal на этапах« pre-build »моего проекта на C #».

    Это было бы слишком просто.

  • Пользователи IDE, которые могут расширяться с помощью «плагинов» (или аналогичных) или которые имеют встроенные редакторы двоичных файлов (hex-редакторы), будут иметь слишком большое преимущество перед пользователями других IDE C #.

    Поэтому эти подвиги также не должны использоваться.

  • Использование других не-ASCII-редакторов (таких как редактор диалоговых окон) явно разрешено!
  • Пользователь, задающий первоначальный вопрос, предложил использовать обратную косую черту в именах функций, например, так: static void M\u0061in()поскольку этот ответ уже был прочитан другими пользователями, он больше не будет принят!
  • Пользователь спросил, будет ли разрешено просто вводить файл .EXE в редактор исходного кода и сохранять файл как «.exe» вместо «.cs». Ответ: Я не сомневаюсь, что это возможно, потому что и действительные двоичные файлы Windows и Linux содержат NUL-байты. Однако, если вы найдете правильный двоичный файл, который может быть создан таким образом, у вас есть правильное решение.

Название этого сайта - «Программирование головоломок и Code Golf» - это «Головоломка программирования», а не «Code Golf». Задача состоит в том, чтобы найти работающее решение перед всеми остальными пользователями, а не найти решение короче, чем все остальные. решения.

Поэтому первый пост, описывающий рабочее решение, побеждает !

Удачи!

Кстати: у меня есть решение, работающее под Visual C # Express 2010.

Мартин Розенау
источник
2
Что мешает мне использовать мою C # IDE в качестве текстового (или двоичного) редактора для непосредственного ввода исполняемого файла?
feersum
2
Какой ответ побеждает в конкурсе? Первый правильный ответ? Вы должны указать условие выигрыша
Джеймс
Если в среде IDE есть какой-либо шестнадцатеричный редактор или что-то подобное, это НЕ допускается Если вам удастся использовать текстовый редактор ASCII для ввода допустимого двоичного файла, это будет разрешено. Обратите внимание, что действительный двоичный файл содержит байты в диапазоне от 0x00 до 0x1F!
Мартин Розенау
2
Я думаю, что это в целом интересная задача. Msgstr "Написать программу на C # без основной". Однако большинство правил касаются того, какие инструменты / IDE использовать, и запрещают определенные подходы. Я хотел бы видеть больше загадок программирования (в отличие от кода-гольфа), но эта недооценка. Я бы порекомендовал использовать песочницу в следующий раз.
Джеймс
4
... Рассмотрим песочницу в следующий раз.
кот

Ответы:

5

C # Интерактивное окно

Откройте интерактивное окно C # («Вид»> «Другие окна»> «Интерактивный C #» в Visual Studio 2015). Я полагаю, что не все IDE будут иметь это.

Этот подход выполняет C # в Интерактивном Окне, чтобы создать C # exe, который печатает желаемую строку без того, чтобы автор когда-либо писал main. В качестве бонуса, ИЛ exe также не содержит 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. Запустите его, чтобы увидеть желаемый результат.

введите описание изображения здесь

В результате ИЛ: введите описание изображения здесь

молоко
источник
На самом деле мне больше нравится этот, чем WPF, потому что у вас вообще нет Main () в вашей сборке.
hstde
Ваше решение интересно. Это второе, поэтому вы выиграете, если пользователи убедят меня, что первое сообщение не является верным решением (по какой-либо причине).
Мартин Розенау
Если вы спросите меня, на самом деле не имеет значения, какой пост выигрывает, поскольку они оба принадлежат одному и тому же пользователю.
16:57
@hstde - Извини, я этого не видел. Спасибо.
Мартин Розенау
@milk Вы опубликовали два действительных решения (ну, некоторые пользователи сомневаются в первом), так что вы выиграли. Поздравляю.
Мартин Розенау
3

Приложение WPF

  1. Создайте новое приложение WPF. введите описание изображения здесь

  2. Заменить все экземпляры MainсMeow введите описание изображения здесь

  3. Переименовать MainWindow.xamlв MeowWindow.xaml. Это автоматически переименует MainWindow.xaml.csв MeowWindow.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 на диск ...

Мартин Розенау
источник