0

CompileAssemblyFromSource を使用して、メイン クラスで 1 つの値を変更しようとしています。しかし、コンパイルすると、「ファイルまたはアセンブリ、またはその依存関係の1つを読み込めませんでした」というエラーが表示され、これは他のクラスの静的値を変更しようとしたときにのみ発生します。しかし、出力を返したり、この FooClass から Console に何かを書き込んだりすると、すべてうまくいきます。しかし、どうすれば他のクラスの値を変更できますか?

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();
            }
        }
    }
}
4

1 に答える 1

0

コードにコンパイル エラーがあるため、型が見つかりません。この方法では、現在のコードのクラスにアクセスできません。少なくとも、メモリ内アセンブリで現在のアセンブリを参照する必要があります。

アップデート

コードに 2 つの問題があります。まず、クラスを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();
            }
        }
    }
}
于 2015-08-23T10:42:03.153 に答える