首页 > 解决方案 > 从实例中获取泛型类型

问题描述

我有一个包含 IMyClass 类型对象的列表。此列表包含类型化类 MyClass<`T> 的实例。我需要从相同 MyClass 类型的列表中取出两个随机对象并对它们执行操作。

我的代码:

var item1 = list[random.Next(list.Count)];
...
var subset = list.OfType<MyClass<item1_T>>().ToList();
var item2 = subset[random.Next(subset.Count)];

我必须在点处填写什么才能获得 item1_T 类型?

标签: c#generics

解决方案


不幸的是,在 C# 中,不可能像您所写的那样使用尖括号符号动态指定泛型类型:

var subset = list.OfType<MyClass<item1_T>>().ToList();

尽管您当然可以OfType<>使用反射调用方法:

var list = new List<IMyClass> { ... };

var item1_T = typeof(int);

var subset = (typeof(Enumerable)
    .GetMethod(nameof(Enumerable.OfType))
    .MakeGenericMethod(typeof(MyClass<>).MakeGenericType(item1_T))
    .Invoke(null, new object[]{ list }) as IEnumerable<IMyClass>)
        .ToList();

但这将是非常低效的。

一个更快的方法是:

var typeToFind = typeof(MyClass<>).MakeGenericType(item1_T);
var subset = list.Where(item => item != null && item.GetType() == typeToFind).ToList();

如果此代码不是性能关键,则使用此解决方案可能无关紧要,否则我建议重构代码以避免使用反射。


推荐阅读