简体   繁体   中英

create (=compile) class at runtime that implements known interface

Is it possible to provide the implementation of an interface by a code snippet that gets compiled at runtime ?

The following does not work (the safe type cast returns "null"):

A complete console application:

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

The cast "as ITest" does not succeed ie. return null. It seems that the type "ITest" defined in the console program is not compatible with the type "ITest" defined in the compiled code snippet.

I know that I can use Reflection to invoke methods, but of course it's more comfortable to access them via an interface.

You have two different ITest interfaces that happen to look the same.
They are not the same type.

Instead, you need to add a reference to the assembly that defines the original interface in the CodeDOM compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM