以编程方式获取类型并将其用作类型参数
Get type programmatically and use it as a typeparam
我想做的是读取我的 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 有一个类型参数。我假设我可以使用类型作为类型参数,因为它代表了我想要的 class 结果。
但是我收到错误:
"The type or namespace name 't' could not be found (are you missing a
using directive or an assembly reference?)".
那么我怎样才能使实际类型用作类型参数而不是字母 't'?
我正在为 windows 8.1 和 windows phone 8.1
创建一个 windows 通用应用程序
编辑:
根据 and Stefan 的建议,我尝试使用反射。我现在有以下代码:
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
}
}
}
这一直到调用调用方法为止。此时发生以下异常:
An exception of type 'System.Reflection.TargetException' occurred in mscorlib.dll but was not handled in user code
Additional information: Object does not match target type.
关于如何解决这个问题的任何线索?
编辑二:
调用方法必须调用为:
var columns = generic.Invoke(database, null);
拨打这样的电话的唯一方法是 use reflection。 <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);
通常你有一个非泛型方法来传递运行时类型,因为泛型在这种情况下没有意义。
我想做的是读取我的 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 有一个类型参数。我假设我可以使用类型作为类型参数,因为它代表了我想要的 class 结果。
但是我收到错误:
"The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?)".
那么我怎样才能使实际类型用作类型参数而不是字母 't'?
我正在为 windows 8.1 和 windows phone 8.1
创建一个 windows 通用应用程序编辑:
根据
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
}
}
}
这一直到调用调用方法为止。此时发生以下异常:
An exception of type 'System.Reflection.TargetException' occurred in mscorlib.dll but was not handled in user code
Additional information: Object does not match target type.
关于如何解决这个问题的任何线索?
编辑二:
调用方法必须调用为:
var columns = generic.Invoke(database, null);
拨打这样的电话的唯一方法是 use reflection。 <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);
通常你有一个非泛型方法来传递运行时类型,因为泛型在这种情况下没有意义。