Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6598737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T18:23:30+00:00 2026-05-25T18:23:30+00:00

I am trying to build a T4 template that will take the method definitions

  • 0

I am trying to build a T4 template that will take the method definitions in an interface and reproduce the signature and call a base method with the passed parameters. The interface defines a multitude of methods so rewriting them every time the interface changes becomes very challenging. Another complication is the interface is a generic interface with possible generic methods and generic parameters. So far, the only way I can find to reproduce the actual signature (without “`1” definitions for generics) is to completely rebuild it, which becomes very cumbersome.

In the case I have a signature like this in my interface:

ICar Drive<TCar>(Expression<Func<TWheel, bool>> wheels, int miles)

Is there any way to completely reproduce that with reflection without having to disect the entire MethodInfo details, or is there a quick way to get the string above out so I can write it in my T4?

Any help would be greatly appreciated!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T18:23:31+00:00Added an answer on May 25, 2026 at 6:23 pm

    When I need to generate code, I often look to the System.CodeDom namespace. It lets you build up a logical representation of code and then get the corresponding source code for what you built. However, I don’t know if I can say that this way isn’t also ‘cumbersome’ as you said in your answer (and this certainly involves ‘dissecting’ the MethodInfo. However, it does give you a pretty decent foundation. Just by passing in the interface you want to ‘clone’, the name of the new class and the base class that you want to extend like so:

    var code = GenerateCode(typeof(TestInterface<>),
                            "MyNewClass",
                            typeof(TestBaseClass<>));
    

    will result in this:

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

    Also, you can change a few characters in the code and switch to the VB provider and you’ll get Visual Basic output (perhaps not useful but kinda 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 GenerateCode beast. Hopefully the comments can explain what’s going on:

    public static string GenerateCode(Type interfaceType, string generatedClassName, Type baseClass)
    {
        //Sanity check
        if (!interfaceType.IsInterface)
            throw new ArgumentException("Interface expected");
    
        //I can't think of a good way to handle closed generic types so I just won't support them
        if (interfaceType.IsGenericType && !interfaceType.IsGenericTypeDefinition)
            throw new ArgumentException("Closed generic type not expected.");
    
        //Build the class
        var newClass = new CodeTypeDeclaration(generatedClassName)
        {
            IsClass = true,
            TypeAttributes = TypeAttributes.Public,
            BaseTypes =
                                    {
                                        //Include the interface and provided class as base classes
                                        MakeTypeReference(interfaceType),
                                        MakeTypeReference(baseClass)
                                    }
        };
    
        //Add type arguments (if the interface is generic)
        if (interfaceType.IsGenericType)
            foreach (var genericArgumentType in interfaceType.GetGenericArguments())
                newClass.TypeParameters.Add(genericArgumentType.Name);
    
        //Loop through each method
        foreach (var mi in interfaceType.GetMethods())
        {
            //Create the method
            var method = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Final,
                Name = mi.Name,
                ReturnType = MakeTypeReference(mi.ReturnType)
            };
    
            //Add any generic types
            if (mi.IsGenericMethod)
                foreach (var genericParameter in mi.GetGenericArguments())
                    method.TypeParameters.Add(genericParameter.Name);
    
            //Add the parameters
            foreach (var par in mi.GetParameters())
                method.Parameters.Add(new CodeParameterDeclarationExpression(MakeTypeReference(par.ParameterType),
                                                                                par.Name));
    
            //Call the same method on the base passing all the parameters
            var allParameters =
                mi.GetParameters().Select(p => new CodeArgumentReferenceExpression(p.Name)).ToArray();
            var callBase = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), mi.Name, allParameters);
    
            //If the method is void, we just call base
            if (mi.ReturnType == typeof(void))
                method.Statements.Add(callBase);
            else
                //Otherwise, we return the value from the call to base
                method.Statements.Add(new CodeMethodReturnStatement(callBase));
    
            //Add the method to our class
            newClass.Members.Add(method);
        }
    
        //TODO: Also add properties if needed?
    
        //Make a "CompileUnit" that has a namespace with some 'usings' and then
        //  our new class.
        var unit = new CodeCompileUnit
        {
            Namespaces =
            {
                new CodeNamespace(interfaceType.Namespace)
                {
                    Imports =
                    {
                        new CodeNamespaceImport("System"),
                        new CodeNamespaceImport("System.Linq.Expressions")
                    },
                    Types =
                    {
                        newClass
                    }
                }
            }
        };
    
        //Use the C# prvider to get a code generator and generate the code
        //Switch this to VBCodeProvider to generate VB Code
        var gen = new CSharpCodeProvider().CreateGenerator();
        using (var tw = new StringWriter())
        {
            gen.GenerateCodeFromCompileUnit(unit, tw, new CodeGeneratorOptions());
            return tw.ToString();
        }
    }
    
    /// <summary>
    /// Helper method for expanding out a type with all it's generic types.
    /// It seems like there should be an easier way to do this but this work.
    /// </summary>
    private static CodeTypeReference MakeTypeReference(Type interfaceType)
    {
        //If the Type isn't generic, just wrap is directly
        if (!interfaceType.IsGenericType)
            return new CodeTypeReference(interfaceType);
    
        //Otherwise wrap it but also pass the generic arguments (recursively calling this method
        //  on all the type arguments.
        return new CodeTypeReference(interfaceType.Name,
                                        interfaceType.GetGenericArguments().Select(MakeTypeReference).ToArray());
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to build template tags that take use a dictionary in settings.py to
I am trying to write a template custom control in C#, ASP.NET that will
I'm trying to build my own template tags. I have no idea why I
I'm trying to create a generic build template for my Makefiles, kind of like
I'm trying build a method which returns the shortest path from one node to
Im trying to build call to action button on my site using jQuery. I
I'm trying to automate the build process for engineering group. As part of that
I have a std::vector< tr1::shared_ptr<mapObject> > that I'm trying build from data contained in
I'm trying to build an InfoPath add-in to allow template editors (as opposed to
I'll begin with a context that will lead to the actual question. I'm trying

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.