Create generic List<T> of T4 generated type

陌路散爱 提交于 2019-12-11 02:47:01

问题


I created simple class using T4 technology.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
using System;

<# var properties = new String[]{"P1", "P2", "P3"}; #>
public class MyGeneratedClass {
<#  
    for(int i = 0; i < 3; i++)
    {
    #>
        private Int32 _<#= properties[i] #> = <#= i #>;
        public Int32 <#= properties[i] #> 
        {
            get 
            {
                return _<#= properties[i] #>;
            }
        } 
    <#
    }
    #>
}

then I created an instance of that generated type like this

static void Main(String[] args)
{
    var template = new Template1();
    var text = template.TransformText();

    CodeDomProvider codeProvider = new CSharpCodeProvider();
    ICodeCompiler compiler = codeProvider.CreateCompiler();

    // add compiler parameters
    var compilerParams = new CompilerParameters
    {
        CompilerOptions = "/target:library /optimize",
        GenerateExecutable = false,
        GenerateInMemory = true,
        IncludeDebugInformation = false
    };
    compilerParams.ReferencedAssemblies.Add("mscorlib.dll");
    compilerParams.ReferencedAssemblies.Add("System.dll");

    // compile the code
    var compilerResults = compiler.CompileAssemblyFromSource(compilerParams, text);

    if (compilerResults.Errors.HasErrors)
        throw new Exception();

    // Создаем экземпляр класса
    var instance = compilerResults.CompiledAssembly.CreateInstance("MyGeneratedClass");
    if (instance == null)
        return;

    var TYPE = instance.GetType();
    var list = new List<TYPE>(); 

}

var list = new List<TYPE>(); generate compile time error:

The type or namespace name 'TYPE' could not be found (are you missing a using directive or an assembly reference?)

  1. Is there any way to create generic list (or some generic collection) with the type of MyGeneratedClass class?
  2. And is there simpler way to create instance of MyGeneratedClass class?

回答1:


Type genericListType = typeof(List<>);
Type[] typeArgs = new[] { instance.GetType() };
var generic = genericListType.MakeGenericType(typeArgs);
System.Collections.IList list = (System.Collections.IList)Activator.CreateInstance(generic);

foreach (dynamic item in list)
{
//whatever
}

Hope i got you right..

EDIT something more usable,

This approach has not much advantages to a ArrayList just there are Exceptions at runtime if you try to add something different then the specific runtime type. While ArrayList will not throw an exception in the case the "wrong" item is added instead there will or will not be an exception if you use the items. I do (even if i don't know the Type at compile time) try to use the concrete generic instead of an open ArrayList, because the exception is raised at the right codeline (IMHO).



来源:https://stackoverflow.com/questions/23245630/create-generic-listt-of-t4-generated-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!