繁体   English   中英

给定一个包含类名称的字符串,然后我如何使用该类作为C#中的类型参数来调用泛型方法?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM