反射-如何在类型列表之间进行比较
本文关键字:之间 比较 列表 类型 反射 | 更新日期: 2023-09-27 18:27:37
我有一个各种类型的实例列表(所有这些类型都派生自超类型)。我需要得到一个子列表,它只包括某些类型或派生的实例。一个简化的例子可以是:
class Program
{
private class A { }
private class B : A { }
private class C : A { }
private class D : C { }
static void Main(string[] args)
{
B b = new B();
C c = new C();
D d = new D();
var typesToHave = new List<Type>();
typesToHave.Add(typeof(C));
var result = new List<A>();
if (typesToHave.Any(t => b.GetType().IsInstanceOfType(t)))
result.Add(b);
if (typesToHave.Any(t => c.GetType().IsInstanceOfType(t)))
result.Add(c);
if (typesToHave.Any(t => d.GetType().IsInstanceOfType(t)))
result.Add(d);
}
}
我希望这里有一个包含c
和d
的列表,但它什么也不返回。
此外(但这是次要的)我不明白为什么不能在lambda表达式中使用is
或as
运算符,比如:
if (typesToHave.Any(t => d is t))
在上面的例子中,我如何获得一个包含c
和d
的列表?
您的参数错误。IsInstanceOfType需要一个实例作为参数,当您传递Type
时。
以下内容应该有效。
if (typesToHave.Any(t => t.IsInstanceOfType(d)))
您可以使用IsAssignableFrom
if (typesToHave.Any(t => t.IsAssignableFrom(d.GetType()))
为了使用is
或as
运算符,您需要提供Type
名称。不是类型实例,这些操作符就是这样工作的。例如:
var list = new List<int>();
var ie = list as IEnumerable<int>;
这也是一个非常好的替代方案:
if (typesToHave.Any(t => b.GetType().IsSubclassOf(t) || b.GetType() == t))
result.Add(b);
if (typesToHave.Any(t => c.GetType().IsSubclassOf(t) || c.GetType() == t))
result.Add(c);
if (typesToHave.Any(t => d.GetType().IsSubclassOf(t) || d.GetType() == t))
result.Add(d);