Я не могу изменить другое значение класса Var с CompileAssemblyFromSource
Я пытаюсь использовать CompileAssemblyFromSource, чтобы изменить 1 значение в моем основном классе. Но когда я компилирую, я получаю ошибку "Не удалось загрузить файл или сборку или одну из ее зависимостей", и это происходит только тогда, когда я пытаюсь изменить статическое значение другого класса. Но если я верну какой-нибудь вывод или напишу что-нибудь на консоли из этого FooClass, то все будет хорошо. Но как я могу изменить значение другого класса?
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
namespace stringToCode
{
class Program
{
public static int q = 0;
static void Main(string[] args)
{
string source = "namespace stringToCode { public class FooClass { public void Execute() { Program.q = 1; } } }";
Console.WriteLine("q=" + q);
using (var foo = new CSharpCodeProvider())
{
var parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
string location = assembly.Location;
if (!String.IsNullOrEmpty(location))
{
parameters.ReferencedAssemblies.Add(location);
}
}
catch (NotSupportedException)
{}
}
var res = foo.CompileAssemblyFromSource(parameters ,source);
var type = res.CompiledAssembly.GetType("FooClass"); //<- here i has error
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
Console.WriteLine("q=" + q);
Console.ReadLine();
}
}
}
}
1 ответ
Вы не можете найти тип, потому что в вашем коде есть ошибка компиляции. Вы не можете получить доступ к классам в вашем текущем коде таким образом. По крайней мере, вы должны ссылаться на текущую сборку в вашей сборке в памяти.
ОБНОВИТЬ
У вас есть две проблемы в вашем коде. Во-первых, вы должны сделать класс Program
общественности. Затем вы должны указать полное имя типа в GetType
метод.
Этот код работает нормально:
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
namespace stringToCode
{
public class Program
{
public static int q = 0;
static void Main(string[] args)
{
string source = "namespace stringToCode { public class FooClass { public void Execute() { Program.q = 1; } } }";
Console.WriteLine("q=" + q);
using (var foo = new CSharpCodeProvider())
{
var parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
string location = assembly.Location;
if (!String.IsNullOrEmpty(location))
{
parameters.ReferencedAssemblies.Add(location);
}
}
catch (NotSupportedException)
{}
}
var res = foo.CompileAssemblyFromSource(parameters ,source);
var type = res.CompiledAssembly.GetType("stringToCode.FooClass"); //<- here i has error
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
Console.WriteLine("q=" + q);
Console.ReadLine();
}
}
}
}