аха, это из той же оперы. в памяти насколько я помню не компилит (создаётся временный файл на диске, просто всё немного спрятано для удобства), но это кардинально ничего не меняет. можно так:
- Код: Выделить всё • Развернуть
/*
@echo off && cls
set WinDirNet=%WinDir%\Microsoft.NET\Framework
IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
%csc% /nologo /out:"%~0.exe" %0
"%~0.exe"
del "%~0.exe"
exit
*/
class HelloWorld
{
static void Main()
{
System.Console.WriteLine("Hello, World!\r\nI am at " + System.Environment.Version);
System.Console.ReadLine();
}
}
или так:
- Код: Выделить всё • Развернуть
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.CSharp;
namespace ConsoleCompiler
{
internal class Program
{
private static void Main(string[] args)
{
// Source code для компиляции
string source =
@"
namespace Foo
{
public class Bar
{
static void Main(string[] args)
{
Bar.SayHello();
}
public static void SayHello()
{
System.Console.WriteLine(""Hello World"");
}
}
}
";
// Настройки компиляции
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters compilerParams = new CompilerParameters
{OutputAssembly = "D:\\Foo.EXE", GenerateExecutable = true};
// Компиляция
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);
// Выводим информацию об ошибках
Console.WriteLine("Number of Errors: {0}", results.Errors.Count);
foreach (CompilerError err in results.Errors)
{
Console.WriteLine("ERROR {0}", err.ErrorText);
}
}
}
}
или чуть посложней
http://www.gotdotnet.ru/blogs/olegaxenow/6520/для динамической компиляции и генерации кода в дотнете плюшек много и эти примеры далеко не всё демонстрируют. на скорую руку делаете простенький клиент-сервер и жонглируете как хотите. хоть просто перекомпилируйте и затем перезапускайте приложение, хоть на ходу как в студии отлаживайте и изменяйте код. куда тут варианту "блокнот" тягаться с его целым вагончиком постоянных, никому не нужных телодвижений?
попыхтеть лучше один раз в самом начале, чем потом постоянно и по чуть-чуть.
ещё пример немного на другую тему. допустим гипотетически мне лень каждый раз делать тонны окошечек для конфига в новом приложении. пишу класс (для наглядности уменьшил, вырезав много буковок и сразу предупреждаю весь код дальше слегка корявый, я пока в том проекте эксперементирую)
- Код: Выделить всё • Развернуть
public class Config : INotifyPropertyChanged
{
public string workDir = String.Empty;
public string workDirInFile = "path.txt";
public string configFile = "config.xml";
public class App : INotifyPropertyChanged
{
public bool launchAtWindowsStartUp = false;
public bool showMainWindowAtStart = true;
public string appName { get; set; }
private bool _b1 = true;
private bool _b2 = false;
public bool b1
{
get { return _b1; }
set
{
if (_b1 != b1)
{
_b1 = value;
NotifyPropertyChanged("b1");
}
}
}
public bool b2
{
get { return _b2; }
set
{
if (_b2 != b2)
{
_b2 = value;
NotifyPropertyChanged("b2");
}
}
}
.......
}
........
}
нужно всего-то создать один UserControl или Page или Window и в коде прописать несколько десятков или сот строчек незамысловатого кода. при/после создания экземпляра этого UserControl/Page/Window "пробежались" по полям, свойствам,... класса и добавили слева список разделов конфига, а справа при выборе раздела будет отображаться список (или не список, это как угодно наворачивать можно) параметров. для свойств (ещё есть поля, методы,...) это работает примерно так
- Код: Выделить всё • Развернуть
private void button1_Click(object sender, RoutedEventArgs e)
{
PropertyInfo[] properties;
Type myType = Core.instance.config.app.GetType();
properties = myType.GetProperties();
foreach (PropertyInfo pi in properties)
{
Type t = pi.PropertyType;
if (t == typeof(System.Boolean))
{
object o = pi.GetValue(Core.instance.config.app, null);
CheckBox c = new CheckBox();
c.IsChecked = (bool)o;
c.Content = pi.Name;
listBox1.Items.Add(c);
}
}
}
если не удалил лишнего при копипасте, то будет выглядеть примерно так
если нужны только паблик или только приват "properties = myType.GetProperties();" меняется на что-то в таком духе "properties = myType.GetProperties(BindingFlags.Public|BindingFlags.Instance);"
в реальном приложении нужно с биндигом визуальных элементов к экземпляру класса разумеется. хотите, там же добавляете валидацию ввода в поля. всё надумано, а я слишком ленив? никто не мешает таким образом прикручивать окна настроек для плагинов к основному приложению. нужно будет только передать ссылку на объект "конфиг", а основная программа уже сама разберётся что где и как отобразить, куда в xml`ке конфига на диске добавить нужный раздел и как с ним потом работать. что можно так сгенерировать условно ограничивается только вашей фантазией и навыками. в дополнение ещё есть
атрибуты, с помощью которых можно очень сильно влиять на то, что будет генерироваться. указывать заголовки или подсказки для элементов, указывать какие поля что нужно пропустить при генерации, предоставить данные для автозаполнения всяких выпадающих списков и прочего, что должно сериализоваться при сохранении конфига на диск и т.д. а всего-то нужно один раз написать код генератора. да, есть моменты, а где их нет? или можно динамическую оптимизацию сделать, как в том же коде регулярок. это и многое другое уже идёт "из коробки"
ловкость рук и никакого мошенничества.
т.е. хочу чего-нить скриптово-интерпретируемого что бы чтот там быстро и удобно разрабатывать, расширять и непонятно как снижать сложность разработки как по мне совсем не аргумент
не штырит концепция.
п.с. хотите быстрей, легче, лучше,... ? забудьте про c++
основная часть проекта должна быть на питоне, яве, шарпе или других .net языков (больше приемлимых кандидатов для общего случая насколько я знаю пока нет). та часть, в которой нужна будет какая-то сверх модная оптимизация выносится в библиотеки (вот их уже хоть на ++, хоть на асме вояйте). опять же в библиотеках всякие opencv и прочий сторонний код. поступать наоборот это очень дорогое удовольствие.