【问题标题】:Create generic List<T> of T4 generated type创建 T4 生成类型的泛型 List<T>
【发布时间】:2014-04-23 13:19:46
【问题描述】:

我使用 T4 技术创建了简单的类。

<#@ 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] #>;
            }
        } 
    <#
    }
    #>
}

然后我创建了一个这样的生成类型的实例

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&lt;TYPE&gt;();生成编译时错误:

找不到类型或命名空间名称“TYPE”(您是否缺少 using 指令或程序集引用?)

  1. 有没有办法创建MyGeneratedClass 类类型的泛型列表(或一些泛型集合)?
  2. 有没有更简单的方法来创建MyGeneratedClass 类的实例?

【问题讨论】:

  • 如果列表项的类型仅在运行时已知,那么使用通用列表有什么意义?

标签: c# list generics t4


【解决方案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
}

希望我没听错..

编辑一些更有用的东西,

这种方法对 ArrayList 没有太多优势,只是如果您尝试添加与特定运行时类型不同的内容,则运行时会出现异常。虽然 ArrayList 在添加“错误”项目的情况下不会引发异常,但如果您使用这些项目,则会或不会出现异常。我确实(即使我在编译时不知道类型)尝试使用具体泛型而不是打开的 ArrayList,因为在正确的代码行(恕我直言)处引发了异常。 p>

【讨论】:

  • 嗯,现在列出的是对象类型。以及如何将列表用作实际的通用列表?例如,添加一些项目,或使用 foreach 循环?我不能使用像 (List??>)list...这样的显式对话...
  • list 属于 List 类型,但由于它是运行时类型,因此在编译时不存在。 Allthought 你可以将它转换为 List 或 IEnumerable (不是通用的)。并在 foreach 中插入项目/使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 2020-09-22
  • 2010-10-22
  • 1970-01-01
相关资源
最近更新 更多