通过只知道类的类型来获取类的类型参数

本文关键字:获取 类型参数 类型 | 更新日期: 2023-09-27 18:27:04

我有一个基本抽象类,它具有来自另一个抽象类的类型参数,如:

public abstract class Database<T> where T : DatabaseItem, new() { //... }
public abstract class DatabaseItem { //... }

然后我就有了一些固有的儿童课程:

public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
//...

现在的问题是,我有一个数据库类型数组,如下所示:

private static readonly Type[] DATABASE_TYPES = new Type[] {
    typeof (ShopDatabase),
    typeof (WeaponDatabase)
};

我想把它们所有的类型参数都作为另一个数组,类似这样:

Type[] databaseItemTypes = MyFunction (DATABASE_TYPES);
// databaseItemTypes will be an array as: [ShopDatabaseItem, WeaponDatabaseItem]

这可能与这个问题类似,但我甚至没有类的实例,所以…

通过只知道类的类型来获取类的类型参数

如果您正在为特定类寻找类型参数,这相对来说很容易:

static Type GetDatabaseTypeArgument(Type type)
{
    for (Type current = type; current != null; current = current.BaseType)
    {
        if (current.IsGenericType && current.GetGenericTypeDefinition() == typeof(Database<>))
        {
            return current.GetGenericTypeArguments()[0];
        }
    }
    throw new ArgumentException("Type incompatible with Database<T>");
}

然后你可以使用:

Type[] databaseItemTypes = DatabaseTypes.Select(GetDatabaseTypeArgument).ToArray();

注意,如果你有一个类:

public class Foo<T> : Database<T>

那么您最终将得到一个Type引用,该引用表示Foo<T>中的T。例如,对于一个基类型为Foo<string>的类型来说,去掉它将是一件棘手的事情。希望你不是那种情况。。。