[英]Given a string which holds the name of a class, how can I then call a generic method using that class as the type parameter in C#?
我在SQLite-Net中使用CreateTable方法,该方法使用类型参数来指定要创建的表类型。 例如:
database.CreateTable<Client>();
客户定义为:
[Table("Client")]
public class Client
{
[PrimaryKey]
public int ClientID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
将使用客户端类中定义的架构创建一个表,以便具有ClientID,Name和Type列。
我想使用一个字符串数组,其中包含要创建的表的名称,以便在数组中命名的所有类上运行CreateTable。 但是我不确定如何在通用方法中使用字符串作为类型参数。
它看起来像这样:
string[] tables = new string[]{"Class1","Class2"};
for(int i = 0; i < tables.Length; i++){
database.CreateTable<tables[i]>();
}
哪个会做与此相同的事情:
database.CreateTable<Class1>():
database.CreateTable<Class2>();
我已经尝试过这样做:
Type tabletype = Type.GetType("Client");
database.CreateTable<tabletype>();
但是我收到一条错误消息,提示“找不到类型或名称空间名称'tabletype'”。 所有表都定义为同一命名空间中的类。
谢谢。
通用类型参数必须是实际的类型名称。 它们不能是计算为Type
对象的表达式。
对于这种情况,SQLite-Net已经具有CreateTable
的非泛型重载 :
Type tabletype = Type.GetType("Client");
database.CreateTable(tabletype);
要么
string[] tables = new[] { "Class1", "Class2" };
for(int i = 0; i < tables.Length; i++) {
Type tableType = Type.GetType(tables[i]);
database.CreateTable(tableType);
}
在更一般的情况下,您必须将反射与MakeGenericMethod
一起使用,以使用来自表达式的Type来调用该方法。
您可以使用反射来做到这一点。
使用您的代码示例:
var database = GetDatabase(); // not sure what this type is.
MethodInfo method = database.GetType().GetMethod("CreateTable");
var assembly = Assembly.GetExecutingAssembly(); // Assume Class1, Class2 etc are here.
var tables = new string[] { "Class1","Class2" };
for(int i = 0; i < tables.Length; i++)
{
MethodInfo generic = method.MakeGenericMethod(assembly.GetType(tables[i]););
generic.Invoke(database, null);
}
首先,在调用Type.GetType
时,您的类型名称应包括名称空间,并且该类型的全名应明确:
public Type GetTableType(string name) {
const string NamespacePrefix = "MyApp.Tables.";
return Type.GetType(NamespacePrefix + name);
}
当拥有类型时,由于无法在编译时确定类型,因此需要使用反射来调用泛型方法:
string tableName = "BlaTable";
var genericMethodTemplate = database.GetType().GetMethod("CreateTable", new Type[0]);
//genericMethodTemplate can be seen as database.CreateTable<T>();
var tableType = GetTableType(tableName);
var genericMethod = genericMethodTemplate.MakeGenericMethod(tableType);
//now the T has been filled in with whatever table was given.
genericMethod.Invoke(database);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.