[英]More efficient way to find if a class inherits an interface?
In C#, currently i'm doing the following code to filter out a specific set of classes that inherit from the CaptureType that is passed to the method. 在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();
}
is there a more efficient/better/faster way to do this? 有没有更有效/更好/更快的方法? if so, please let me know :) 如果是这样,请让我知道:)
if (plugin.Interface is CaptureType)
{
// inherits
}
or even 甚至
return Bot.AutoPlugins.Where(i => i.Interface is CaptureType).ToArray();
UPD : if CaptureType
is strongly required to be returned: UPD :如果强烈要求返回CaptureType
:
return Bot.AutoPlugins.Where(i => i.Interface is CaptureType)
.Select(i => i as CaptureType)
.ToArray();
(yes, now it looks a little more bloated, but there is another laconic answer with OfType()
in this thread, so i will not repeat it) (是的,现在看起来有点肿,但是在该线程中还有OfType()
另一个简洁答案,所以我不再重复)
I would actually suggest the following: 我实际上建议以下内容:
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;
}
}
This has a number of advantages: 这具有许多优点:
is
keyword, you basically end up doing two type casts (the evaluation of x is y
is basically a type cast and has the same performance characteristics) so if you do ( if (x is Y) { blah = (Y)x }
you're doing two casts instead of just one that as
and a null
check requires. 如果使用is
关键字,则基本上会进行两次类型转换( x is y
的评估基本上x is y
并且具有相同的性能特征),如果这样做( if (x is Y) { blah = (Y)x }
您正在执行两次强制转换,而不仅仅是as
和null
检查所需的强制转换。 yield return
stuff) you don't need to create a temporary List<CaptureType>
in memory, convert it to an array and then return the array. 通过使用插入器(即yield return
东西),您无需在内存中创建临时List<CaptureType>
,将其转换为数组,然后返回该数组。 Also note the where CaptureType : class
. 另外还要注意where CaptureType : class
。 Since CaptureType
is an interface, you can be sure that it'll always pass, but that constraint is required in order to use the as
keyword. 由于CaptureType
是一个接口,因此可以确保它总是会通过,但是要使用as
关键字,必须具有该约束。 If you have a "base" interface that all your plugins implement (eg IPlugin
maybe) then you could replace the where CaptureType : class
with where CaptureType : IPlugin
instead. 如果您有一个所有插件都实现的“基本”接口(例如,可能是IPlugin
),则可以将where CaptureType : class
替换为where CaptureType : IPlugin
。
I would suggest a simple 我建议一个简单的
return Bot.AutoPlugins.Select (p => p.Interface).OfType<CaptureType> ().ToArray ();
EDIT: 编辑:
Thinking more, this is potentially less efficient than doing the a Where then Select combination, as in my example you do the select for every item, then limit by type... 仔细想想,这可能比使用“先从后选”组合的效率低,如在我的示例中,您先对每个项目进行选择,然后按类型进行限制...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.