0

実行時にコンパイルされるコード スニペットによってインターフェイスの実装を提供することは可能ですか?

以下は機能しません (安全な型キャストは「null」を返します):

完全なコンソール アプリケーション:

using System;
using System.Collections.Generic;

namespace Foo
{
    using System.CodeDom.Compiler;

    using Microsoft.CSharp;

    class Program
    {
        static void Main(string[] args)
        {
            // code snippet to compile:   
            string source =@"namespace Foo {

    public class Test:ITest
    {
        public void Write()
        {
            System.Console.WriteLine(""Hello World"");
        }
    }

    public interface ITest
    {

        void Write();
    }
}
   ";//end snippet

      // the "real" code:

            Dictionary<string, string> providerOptions = new Dictionary<string, string>
                {
                    {"CompilerVersion", "v4.0"}
                };
            CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);

            CompilerParameters compilerParams = new CompilerParameters
            {
                GenerateInMemory = true,
                GenerateExecutable = false
            };

            CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

            if (results.Errors.Count == 0)
            {

            }

            ITest test = results.CompiledAssembly.CreateInstance("Foo.Test") as Foo.ITest;

            test.Write(); // will crash here because it is "null"

            Console.ReadLine();
        }
    }

    public interface ITest
    {

        void Write();
    }
}

「as ITest」のキャストは成功しません。null を返します。コンソール プログラムで定義されているタイプ「ITest」は、コンパイルされたコード スニペットで定義されているタイプ「ITest」と互換性がないようです。

リフレクションを使用してメソッドを呼び出すことができることは知っていますが、もちろん、インターフェイスを介してメソッドにアクセスする方が快適です。

4

1 に答える 1

5

ITestたまたま同じように見える2 つの異なるインターフェイスがあります。
それらは同じタイプではありません。

代わりに、CodeDOM コンパイラで元のインターフェイスを定義するアセンブリへの参照を追加する必要があります。

于 2013-08-06T15:02:08.560 に答える