为什么编译器不允许将Class.System.Type作为T参数传递给泛型方法

时间:2018-09-20 13:14:33

标签: c# vb.net generics types

编译错误:

  

Visual Basic.NET 编译错误:“类型t未定义”

   C#编译错误:“ t”是变量,但像类型一样使用

为什么我不能这样做:

VB:

For i = 0 To dt.Columns.Count - 1
    Dim t As Type = dt.Columns(i).DataType
    Dim field = dt.GetValueSafely(Of t)(dt.Columns(i).ColumnName, 0) ' compilation error'
Next

C#:

for (int i = 0; i <= dt.Columns.Count - 1; i++)
{
    Type t = dt.Columns[i].DataType;
    var field = dt.GetValueSafely<t>(dt.Columns[i].ColumnName, 0); // compilation error
}

还有其他实现我想要做的事情吗?还是必须直接声明类型?

2 个答案:

答案 0 :(得分:0)

在调用使用泛型的函数时,编译器希望您为它赋予小于/大于符号(“ <”和“>”)之间的类/结构名称。

您正在向其传递一个实例变量(t):这是一个实际的对象实例,而不是编译器所期望的类/结构名称。

完成目标的一种方法是通过反射调用GetValueSafety<T>()方法。您基本上是通过使用对象MethodInfo的类型从要调用的方法中检索dt的,然后指定该方法的通用类型参数,然后调用它(传递参数您需要)。就您而言,这可以归结为以下内容:

MethodInfo method = dt.GetType().GetMethod("GetValueSafety");
MethodInfo callableMethod = method.MakeGenericMethod(t);

Object [] callParams = new Object[] { dt.Columns[i].ColumnName, 0 };
callableMethod.Invoke(dt, callParams);

答案 1 :(得分:-1)

因为你用错了

编译器已经告诉您您的错误,val a = List(1,2,3,4,5) val b = a.filter(x => x > 3) 不是类型而是变量

要做的是,要存档的内容,则需要在该位置使用实际类型t

由于无法在运行时确定类型的原因,因此有很多文档,例如SO。 Setting generic type at runtime