在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();
}
有更高效/更好/更快的方法吗?如果是的话,请告诉我:))
答案 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;
}
}
这有许多优点:
is
关键字,你基本上最终会做两个类型转换(x is y
的评估基本上是一个类型转换并具有相同的性能特征)所以如果你这样做({{ 1}}您正在进行两次演员,而不只是一次if (x is Y) { blah = (Y)x }
和as
支票需要。null
内容),您不需要在内存中创建临时yield return
,将其转换为数组然后返回数组。 另请注意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组合效率低,如在我的示例中,您为每个项目执行选择,然后按类型限制...