如何检查对象是否属于 C# 中的任何给定类型

How to check if object is of any of given types in C#

我正在使用 Unity Engine,其中有一个基础 class Component 和多个从中派生的 classes,包括 TransformMeshRenderer以及我创建的许多 classes。

我想执行一个动作(在本例中 Destroy 所有非类型的组件:TransformMeshRendererMeshFilterColliderBuildMenuItem)。我的基本方法如下所示:

Component[] components = obj.GetComponents<Component>();
foreach (var component in components) {
    if (component is MeshFilter)
        continue;
    if (component is MeshRenderer)
        continue;
    if (component is Transform)
        continue;
    if (component is Collider)
        continue;
    if (component is BuildMenuItem)
        continue;

    Destroy(component);
}

在我看来,它看起来很难看,我发现缩短它的唯一方法是使用 || 运算符,但它并没有解决很多问题,IMO 看起来更糟。有更简洁的实现方式吗?

您可以初始化 Type 的集合(例如 List<Type>HashSet<Tepe> 等),将所有需要的类型添加到其中(typeof(Transform)、.. .),然后使用 Contains 检查组件类型是否在该集合中。

var types = new HashSet<Type> {typeof(Transform), typeof(MeshRenderer)};

Component[] components = obj.GetComponents<Component>();
foreach (var component in components.Where(c => !types.Contains(c.GetType())))
{
    Destroy(component);
}

已更新:

Type[] types = { typeof(Transform), typeof(MeshRenderer) };

Component[] components = obj.GetComponents<Component>();
foreach (var component in components.Where(c => !types.Any(x => c.GetType().IsAssignableFrom(x))))
{
    Destroy(component);
}

创建接口INotDestroyable,使不可破坏类型TransformMeshRendererMeshFilterColliderBuildMenuItem实现它,然后在你的循环中检查元素是否没有实现它。接口不必定义任何属性或成员。