Reputation: 17213
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.
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 :)
Upvotes: 1
Views: 725
Reputation: 11495
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...
Upvotes: 0
Reputation: 254926
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:
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)
Upvotes: 4
Reputation: 72658
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.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. Also note the 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. If you have a "base" interface that all your plugins implement (e.g. IPlugin
maybe) then you could replace the where CaptureType : class
with where CaptureType : IPlugin
instead.
Upvotes: 3