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

时间:2015-12-17 06:40:03

标签: c# inheritance types abstract type-parameter

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

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 {}

//...

现在的问题是,我有数据库 Type 数组:

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]

它可能类似于question,但我甚至没有该类的实例,所以......

1 个答案:

答案 0 :(得分:2)

如果您正在寻找特定班级的类型参数,那么相对就容易了:

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中获得代表T的{​​{1}}引用。例如,对于基类型为Foo<T>的类型,去掉它会很棘手。希望你不是那种情况......