Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
899
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Как я могу динамически оценивать код C#?
Я могу сделать eval("something()"); , чтобы выполнить код динамически в JavaScript. Есть ли способ для меня сделать то же самое в C#?
Пример того, что я пытаюсь сделать: у меня есть целочисленная переменная (скажем, i), и у меня есть несколько свойств по именам: "Property1", "Property2", "Property3" и т. д.
Теперь я хочу выполнить некоторые операции над свойством "Property i " в зависимости от значения i .
Это действительно просто с Javascript. Есть ли какой-нибудь способ сделать это с C#?
К сожалению, C#-это не такой динамичный язык, как этот.
Однако вы можете создать файл исходного кода C#, полный класса и всего остального, и запустить его через провайдер CodeDom для C#, скомпилировать его в assembly, а затем выполнить его.
Этот пост форума на MSDN содержит ответ с некоторым примером кода вниз по странице.:
создать анонимный метод из строки?
Я бы не сказал, что это очень хорошее решение, но оно все равно возможно.
Какой код вы собираетесь ожидать в этой строке? Если это незначительное подмножество допустимого кода, например просто математические выражения, то могут существовать и другие альтернативы.
Edit: Ну, это учит меня сначала внимательно читать вопросы. Да, отражение могло бы оказать вам здесь некоторую помощь.
Если разделить строку на ; Во-первых, чтобы получить отдельные свойства, можно использовать следующий код для получения объекта PropertyInfo для конкретного свойства класса, а затем использовать этот объект для управления конкретным объектом.
String propName = "Text";
PropertyInfo pi = someObject.GetType().GetProperty(propName);
pi.SetValue(someObject, "New Value", new Object[0]);
Ссылка: PropertyInfo.SetValue Метод
Использование сценария Roslyn API (дополнительные примеры здесь ):
// add NuGet package 'Microsoft.CodeAnalysis.Scripting'
using Microsoft.CodeAnalysis.CSharp.Scripting;
await CSharpScript.EvaluateAsync("System.Math.Pow(2, 4)") // returns 16
Вы также можете запустить любой фрагмент кода:
var script = await CSharpScript.RunAsync(@"
class MyClass
{
public void Print() => System.Console.WriteLine(1);
}")
И ссылайтесь на код, который был сгенерирован в предыдущих запусках:
await script.ContinueWithAsync("new MyClass().Print();");
Не совсем. Вы можете использовать рефлексию для достижения желаемого, но это будет далеко не так просто, как в Javascript. Например, если вы хотите установить частное поле объекта на что-то, вы можете использовать эту функцию:
protected static void SetField(object o, string fieldName, object value)
{
FieldInfo field = o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(o, value);
}
Это функция eval под c#. я использовал ее для преобразования анонимных функций (Lambda выражений)из строки. Источник: http://www.codeproject.com/KB/cs/evalcscode.aspx
public static object Eval(string sCSCode) {
CSharpCodeProvider c = new CSharpCodeProvider();
ICodeCompiler icc = c.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.xml.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.windows.forms.dll");
cp.ReferencedAssemblies.Add("system.drawing.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n" );
sb.Append("using System.Xml;\n");
sb.Append("using System.Data;\n");
sb.Append("using System.Data.SqlClient;\n");
sb.Append("using System.Windows.Forms;\n");
sb.Append("using System.Drawing;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return "+sCSCode+"; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
if( cr.Errors.Count > 0 ){
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
"Error evaluating cs code", MessageBoxButtons.OK,
MessageBoxIcon.Error );
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
Я написал проект с открытым исходным кодом Dynamic Expresso, который может преобразовать текстовое выражение, написанное с использованием синтаксиса C#, в делегаты (или дерево выражений). Выражения анализируются и преобразуются в деревья выражений без использования компиляции или отражения.
Вы можете написать что-то вроде:
var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");
или
var interpreter = new Interpreter()
.SetVariable("service", new ServiceExample());
string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";
Lambda parsedExpression = interpreter.Parse(expression,
new Parameter("x", typeof(int)));
parsedExpression.Invoke(5);
Моя работа основана на статье Скотта ГУ http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
Все это определенно сработает. Лично для этой конкретной проблемы я, вероятно, выбрал бы несколько иной подход. Может быть, что-то вроде этого:
class MyClass {
public Point point1, point2, point3;
private Point[] points;
public MyClass() {
//...
this.points = new Point[] {point1, point2, point3};
}
public void DoSomethingWith(int i) {
Point target = this.points[i+1];
// do stuff to target
}
}
При использовании подобных шаблонов вы должны быть осторожны, чтобы ваши данные хранились по ссылке, а не по значению. Другими словами, Не делайте этого с примитивными людьми. Вы должны использовать их большие раздутые аналоги класса.
Я понял, что это не совсем тот вопрос, но на него был довольно хороший ответ, и я подумал, что, возможно, альтернативный подход может помочь.
Я не знаю сейчас, если вы абсолютно хотите выполнить C# операторов, но вы уже можете выполнить Javascript оператора в C# 2.0. Это может сделать библиотека с открытым исходным кодом Jint . Это интерпретатор Javascript для .NET. Передайте программу Javascript, и она будет работать внутри вашего приложения. Вы даже можете передать объект C# в качестве аргументов и сделать на нем автоматизацию.
Кроме того, если вы просто хотите оценить выражение в своих свойствах, попробуйте NCalc .
Вы также можете реализовать Webbrowser, а затем загрузить html-файл, который содержит javascript.
Затем вы переходите к методу document.InvokeScript в этом браузере. Возвращаемое значение функции eval может быть поймано и преобразовано во все, что вам нужно.
Я делал это в нескольких проектах, и это прекрасно работает.
Надеюсь, это поможет
Вы можете сделать это с помощью функции прототипа:
void something(int i, string P1) {
something(i, P1, String.Empty);
}
void something(int i, string P1, string P2) {
something(i, P1, P2, String.Empty);
}
void something(int i, string P1, string P2, string P3) {
something(i, P1, P2, P3, String.Empty);
}
и так далее...
Я написал пакет SharpByte.Dynamic, чтобы упростить задачу динамической компиляции и выполнения кода. Код может быть вызван на любом объекте контекста с помощью методов расширения, как описано далее здесь .
Например,
someObject.Evaluate<int>("6 / {{{0}}}", 3))
возврат 3;
someObject.Evaluate("this.ToString()"))
возвращает строковое представление объекта контекста;
someObject.Execute(@
"Console.WriteLine(""Hello, world!"");
Console.WriteLine(""This demonstrates running a simple script"");
");
запускает эти операторы как сценарий и т. д.
Исполняемые файлы можно легко получить с помощью фабричного метода, как показано в Примере здесь-все, что вам нужно, это исходный код и список любых ожидаемых именованных параметров (токены встроены с использованием трехбрекетной нотации, такой как {{0}}}, чтобы избежать коллизий с string.Format(), а также синтаксисов, подобных рулям):
IExecutable executable = ExecutableFactory.Default.GetExecutable(executableType, sourceCode, parameterNames, addedNamespaces);
Каждый исполняемый объект (скрипт или выражение) является потокобезопасным, может быть сохранен и повторно использован, поддерживает ведение журнала из скрипта, хранит информацию о времени и последнем исключении, если оно возникло, и т. д. Существует также метод Copy(), скомпилированный на каждом из них, чтобы позволить создавать дешевые копии, т. е. использовать исполняемый объект, скомпилированный из скрипта или выражения, в качестве шаблона для создания других.
Накладные расходы на выполнение уже скомпилированного скрипта или оператора относительно невелики, на скромном оборудовании они составляют менее микросекунды, а уже скомпилированные скрипты и выражения кэшируются для повторного использования.
Вы можете проверить библиотеку Heleonix.Reflection . Он предоставляет методы для get/set/invoke членов динамически, включая вложенные члены, или если член четко определен, вы можете создать getter/setter (lambda, скомпилированный в делегат), который быстрее, чем отражение:
var success = Reflector.Set(instance, null, $"Property{i}", value);
Или если число свойств не бесконечно, вы можете создавать сеттеры и чешировать их (сеттеры быстрее, так как они компилируются делегатами):
var setter = Reflector.CreateSetter<object, object>($"Property{i}", typeof(type which contains "Property"+i));
setter(instance, value);
Сеттеры могут иметь тип Action<object, object> , но экземпляры могут отличаться во время выполнения, поэтому вы можете создавать списки сеттеров.
Я пытался получить значение члена структуры (класса) по его имени. Эта структура не была динамичной. Все ответы не работали, пока я наконец не получил его:
public static object GetPropertyValue(object instance, string memberName)
{
return instance.GetType().GetField(memberName).GetValue(instance);
}
Этот метод возвращает значение элемента по его имени. Он работает на регулярной структуре (классе).
К сожалению, C# не имеет никаких собственных средств для выполнения именно того, что вы просите.
Однако моя программа C# eval позволяет оценить код C#. Он обеспечивает оценку кода C# во время выполнения и поддерживает множество операторов C#. Фактически, этот код можно использовать в любом проекте .NET, однако он ограничен использованием синтаксиса C#. Взгляните на мой сайт, http://csharp-eval.com , для получения дополнительной информации.
правильный ответ заключается в том, что вам нужно кэшировать весь результат, чтобы сохранить низкое использование mem0ry.
пример будет выглядеть так
TypeOf(Evaluate)
{
"1+1":2;
"1+2":3;
"1+3":5;
....
"2-5":-3;
"0+0":1
}
и добавьте его в список
List<string> results = new List<string>();
for() results.Add(result);
сохраните идентификатор и используйте его в коде
надеюсь, это поможет