查找类是否继承接口的更有效方法?

时间:2010-09-23 02:18:48

标签: c# reflection inheritance

在C#中,我正在使用以下代码来过滤掉从传递给方法的CaptureType继承的一组特定类。

    public static CaptureType[] ListPluginsWith<CaptureType>()
    {
        List<CaptureType> plugins = new List<CaptureType>();
        foreach (var plugin in Bot.AutoPlugins)
        {
            CaptureType plug;
            try
            {
                if ((plug = (CaptureType)plugin.Interface) != null)
                {
                    plugins.Add(plug);
                }
            }
            catch
            {
                //doesn't inherit
            }
        }
        return plugins.ToArray();
    }

有更高效/更好/更快的方法吗?如果是的话,请告诉我:))

3 个答案:

答案 0 :(得分:4)

if (plugin.Interface is CaptureType)
{
    // inherits
}

甚至

return Bot.AutoPlugins.Where(i => i.Interface is CaptureType).ToArray();

UPD :强烈要求退回CaptureType

return Bot.AutoPlugins.Where(i => i.Interface is CaptureType)
                      .Select(i => i as CaptureType)
                      .ToArray();

(是的,现在它看起来有点臃肿,但在这个帖子中有OfType()的另一个简洁的答案,所以我不再重复了)

答案 1 :(得分:3)

我实际上建议如下:

public static IEnumerable<CaptureType> ListPluginsWith<CaptureType>()
   where CaptureType : class
{
    foreach (var plugin in Bot.AutoPlugins)
    {
        CaptureType plug = plugin.Interface as CaptureType;
        if (plug != null)
            yield return plug;
    }
}

这有许多优点:

  1. 如果你使用is关键字,你基本上最终会做两个类型转换(x is y的评估基本上是一个类型转换并具有相同的性能特征)所以如果你这样做({{ 1}}您正在进行两次演员,而不只是一次if (x is Y) { blah = (Y)x }as支票需要。
  2. 通过使用interator(即null内容),您不需要在内存中创建临时yield return,将其转换为数组然后返回数组。
  3. 另请注意List<CaptureType>。由于where CaptureType : class是一个接口,因此您可以确保它始终通过,但为了使用CaptureType关键字,则需要该约束。如果您有一个所有插件都可以实现的“基础”界面(例如,可能是as),那么您可以将IPlugin替换为where CaptureType : class

答案 2 :(得分:0)

我建议一个简单的

return Bot.AutoPlugins.Select (p => p.Interface).OfType<CaptureType> ().ToArray ();

编辑:

考虑更多,这可能比执行Where then Select组合效率低,如在我的示例中,您为每个项目执行选择,然后按类型限制...