2013-08-06 41 views
0

是否有可能提供的接口由都在运行时编译的代码片断执行?创建(=编译)在运行时类,它实现已知接口

下不工作(安全型投回报“空”):

一个完整的控制台应用程序:

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 [email protected]"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(); 
    } 
} 

演员“为ITEST”不成功即。返回null。 看来,在控制台程序中定义的类型“ITEST”是不是在编译的代码片段中定义的类型“ITEST”兼容。

我知道我可以使用反射来调用方法,当然它更舒适的通过接口来访问它们。

回答

5

你有两个不同的ITest接口碰巧看起来是一样的。
它们不是同一类型。

相反,你需要添加一个引用到定义在CodeDOM的编译器的初始界面的组件。

+0

谢谢。所以我只需要添加这一行:compilerParams.ReferencedAssemblies.Add(typeof(Program).Assembly.Location);当然还要删除代码片段中的ITest接口。 – fritz