Есть ли способ получить доступ к свойствам из экземпляров классов, созданных с использованием в памяти кода, скомпилированного Roslyn в c# - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь создать простой метод, который скомпилирует некоторый произвольный класс и затем предоставит мне доступ к свойствам этих классов, используя. Net Core 3.0 и компилятор Roslyn.

Я успешно получил код чтобы скомпилировать и создать экземпляр, однако он выглядит как все stati c и private.

Вот код:

        private void ExecuteOnCompileCommand()
        {

            var code = @"
                          using System;

                          namespace CompileTest
                          {

                              public class Test
                              {
                                   public int y { get; set; }
                                   public int x { get; set; }

                              }
                           }";

            var system =  MetadataReference.CreateFromFile(typeof(object).Assembly.Location);

            var compilation = CSharpCompilation.Create(
                    "_" + Guid.NewGuid().ToString("D"),
                    syntaxTrees: new SyntaxTree[] { CSharpSyntaxTree.ParseText(code) },
                    references: new [] {system },
                    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                var compilationResult = compilation.Emit(ms);

                if (compilationResult.Success)
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    _assembly = Assembly.Load(ms.ToArray());
                }
            }

            //create instance of class
            var instance = _assembly.CreateInstance(_assembly.DefinedTypes.First().FullName);

    } 

Как только он скомпилируется и запустится, я достигаю точки останова в конце метода и вижу x, y и он говорит: имеет тип Test, однако я не могу установить эти переменные или даже установить другую переменную в их значение.

1 Ответ

1 голос
/ 02 апреля 2020

Не обычным способом, но

Если вы создадите его как

dynamic instance = _assembly.CreateInstance(_assembly.DefinedTypes.First().FullName);

, вы можете сделать это:

instance.x = 42;

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

Спасибо, и будьте в безопасности.

...