以编程方式获取类型并将其用作类型参数

本文关键字:类型参数 编程 方式获 取类型 | 更新日期: 2023-09-27 17:54:50

我想做的是读取lex.db数据库中的所有内容。最好是按预先定义的大小进行分页。我做了以下的事情:

DbInstance database = GetDatabase();
var tables = database.AllTables();
foreach (var table in tables)
{
    string str = table.ToString();
    str = str.Replace("Lex.Db.DbTable`1[", string.Empty);
    str = str.Replace("]", string.Empty);
    Type t = Type.GetType(str);
    if (t != null)
    {
    var columns = database.ReadAll<t>();
    //handle all columns
    }
}

问题在于函数ReadAll有一个类型参数。我假设我可以使用类型作为typeparam,因为它代表了我想要得到结果的类。

但是我得到错误:

"类型或命名空间名称't'无法找到(您是否缺少一个使用指令还是程序集引用?)".

那么我怎样才能使实际类型被用作类型参数而不是字母"t"呢?

我正在创建一个windows 8.1和windows phone 8.1的windows通用应用程序

编辑:

基于romkyns和Stefan Steinegger给出的建议,我尝试使用反射。我现在有了下面的代码:

DbInstance database = DbInstance.GetInstance();
System.Type thisType = database.GetType();
TypeInfo thisTypeInfo = thisType.GetTypeInfo();
MethodInfo method = thisTypeInfo.GetDeclaredMethod("LoadAll");
var tables = database.AllTables();
foreach (var table in tables)
{
    string str = table.ToString();
    str = str.Replace("Lex.Db.DbTable`1[", string.Empty);
    str = str.Replace("]", string.Empty);
    Type t = Type.GetType(str);
    if (t != null)
    {
        MethodInfo generic = method.MakeGenericMethod(t);
        object[] parameters = { this, null };
        var columns = generic.Invoke(database, parameters);
        if (columns != null)
        {
            //handle columns
        }
    }
}

直到调用invoke方法为止。此时出现以下异常:

System.Reflection类型的异常。TargetException'在mscorlib.dll中发生,但未在用户代码中处理

附加信息:Object does not match target type.

有关于如何解决这个问题的线索吗?

编辑II:

调用方法必须以如下方式调用:

var columns = generic.Invoke(database, null);

以编程方式获取类型并将其用作类型参数

进行这样的调用的唯一方法是使用反射。<T>在编译时应该是已知的,但在您的情况下它不是,因此您不能这样做。

这样的api通常带有直接接受Type的重载。检查一下你的是否有。它可能看起来像这样:

database.ReadAll(t);

必须使用反射。不能以其他方式组合运行时类型和编译时类型:

(可能是错误的,只是记住它看起来像这样:)

var dbInstanceType = typeof(DbInstance);
var readAllMethod = dbInstanceType.GetMethod("ReadAll");
var typedReadAllMethod = readAllMethod.BuildGenericMethod(t);
var result = typedReadAllMethod.Invoke(dbInstanceType);

通常在运行时类型中传递一个非泛型方法,因为在这种情况下泛型没有意义。