Действительно ли возможно динамично скомпилировать и выполнить фрагменты кода C#?

Попробуйте изменить

Text.defaultProps.allowFontScaling = AppConfig.allowTextFontScaling 

на

Text.allowFontScaling = AppConfig.allowTextFontScaling . 

. Если это не работает, необходимо явно установить allowFontScaling = false для всех экземпляров Text

.
164
задан sepp2k 8 March 2019 в 20:53
поделиться

3 ответа

The best solution in C#/all static .NET languages is to use the CodeDOM for such things. (As a note, its other main purpose is for dynamically constructing bits of code, or even whole classes.)

Here's a nice short example take from LukeH's blog, which uses some LINQ too just for fun.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

class Program
{
    static void Main(string[] args)
    {
        var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
        parameters.GenerateExecutable = true;
        CompilerResults results = csc.CompileAssemblyFromSource(parameters,
        @"using System.Linq;
            class Program {
              public static void Main(string[] args) {
                var q = from i in Enumerable.Range(1,100)
                          where i % 2 == 0
                          select i;
              }
            }");
        results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
    }
}

The class of primary importance here is the CSharpCodeProvider which utilises the compiler to compile code on the fly. If you want to then run the code, you just need to use a bit of reflection to dynamically load the assembly and execute it.

Here is another example in C# that (although slightly less concise) additionally shows you precisely how to run the runtime-compiled code using the System.Reflection namespace.

167
ответ дан 23 November 2019 в 21:14
поделиться

Для компиляции вы можете просто инициировать вызов оболочки для компилятора csc. У вас может быть головная боль, пытаясь удержать ваши пути и переключатели прямыми, но это, безусловно, можно сделать.

Примеры C # Corner Shell

РЕДАКТИРОВАТЬ : Или еще лучше, используйте CodeDOM, как предложил Нолдорин ...

3
ответ дан 23 November 2019 в 21:14
поделиться

Другие уже дали хорошие ответы о том, как генерировать код во время выполнения, поэтому я Я подумал, что расскажу о вашем втором абзаце. У меня есть некоторый опыт в этом, и я просто хочу поделиться уроком, который я извлек из этого опыта.

По крайней мере, я мог бы определить интерфейс, который им потребуется реализовать, то они предоставят «раздел» кода, который реализовал это интерфейс.

У вас могут возникнуть проблемы, если вы используете интерфейс в качестве базового типа. Если в будущем вы добавите один новый метод в интерфейс , то все существующие клиентские классы, которые реализуют интерфейс , теперь станут абстрактными, то есть вы не сможете компилировать или создавать экземпляры. предоставленный клиентом класс во время выполнения.

У меня возникла эта проблема, когда пришло время добавить новый метод примерно через 1 год после доставки старого интерфейса и после распространения большого количества «устаревших» данных, которые необходимо было поддерживать. Я закончил тем, что создал новый интерфейс, который унаследовал от старого, но этот подход усложнил загрузку и создание экземпляров клиентских классов, потому что я должен был проверить, какой интерфейс был доступен.

Одним из решений, о котором я думал в то время, было вместо этого использовать фактический класс в качестве базового типа, такого как приведенный ниже. Сам класс может быть помечен как абстрактный, но все методы должны быть пустыми виртуальными методами (не абстрактными методами). Затем клиенты могут переопределить методы, которые они хотят, и я могу добавить новые методы в базовый класс, не аннулируя существующий клиентский код.

public abstract class BaseClass
{
    public virtual void Foo1() { }
    public virtual bool Foo2() { return false; }
    ...
}

Независимо от того, применима ли эта проблема, вы должны подумать о том, как создать версию интерфейса между вашей кодовой базой и клиентом. код.

38
ответ дан 23 November 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: