When I need to generate code, I often look at the System.CodeDom
namespace. It allows you to create a logical representation of the code, and then get the appropriate source code for what you created. However, I don’t know if I can say that this method is not as “cumbersome” as you said in your answer (and this, of course, assumes a “dissection” of MethodInfo
. However, this gives you a pretty decent foundation Just by going to the interface that you want to "clone", the name of the new class and base class that you want to extend as follows:
var code = GenerateCode(typeof(TestInterface<>), "MyNewClass", typeof(TestBaseClass<>));
will result in the following:
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.237 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace MyNamespace { using System; using System.Linq.Expressions; public class MyNewClass<TWheel> : TestInterface<TWheel>, TestBaseClass<TWheel> { public MyNamespace.ICar Drive<TCar>(Expression<Func<TWheel, bool>> wheels, int miles) { return base.Drive(wheels, miles); } } }
Alternatively, you can change a few characters in the code and switch to the VB provider, and you will get Visual Basic output (perhaps not useful, but just cool):
'------------------------------------------------------------------------------ ' <auto-generated> ' This code was generated by a tool. ' Runtime Version:4.0.30319.237 ' ' Changes to this file may cause incorrect behavior and will be lost if ' the code is regenerated. ' </auto-generated> '------------------------------------------------------------------------------ Option Strict Off Option Explicit On Imports System Imports System.Linq.Expressions Namespace MyNamespace Public Class MyNewClass(Of TWheel) Inherits TestInterface(Of TWheel) Implements TestBaseClass(Of TWheel) Public Function Drive(Of TCar)(ByVal wheels As Expression(Of Func(Of TWheel, Boolean)), ByVal miles As Integer) As MyNamespace.ICar Return MyBase.Drive(wheels, miles) End Function End Class End Namespace
Here is the Beast GenerateCode
. Hopefully the comments can explain what happens:
public static string GenerateCode(Type interfaceType, string generatedClassName, Type baseClass) {