在运行时创建(=编译)实现已知接口的类

本文关键字:接口 实现 创建 运行时 编译 | 更新日期: 2023-09-27 18:26:45

是否可以通过在运行时编译的代码片段来提供接口的实现?

以下操作不起作用(安全类型强制转换返回"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"类型不兼容。

我知道我可以使用Reflection来调用方法,但通过接口访问它们当然更方便。

在运行时创建(=编译)实现已知接口的类

您有两个不同的ITest接口,它们看起来恰好相同
它们不是同一类型。

相反,您需要在CodeDOM编译器中添加对定义原始接口的程序集的引用。