C# 找到类是否继承接口的更有效方法?
在C中,目前我正在执行以下代码以过滤掉从传递给方法的CaptureType继承的一组特定类C# 找到类是否继承接口的更有效方法?,c#,reflection,inheritance,C#,Reflection,Inheritance,在C中,目前我正在执行以下代码以过滤掉从传递给方法的CaptureType继承的一组特定类 public static CaptureType[] ListPluginsWith<CaptureType>() { List<CaptureType> plugins = new List<CaptureType>(); foreach (var plugin in Bot.AutoPlugins)
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();
}
有没有更有效/更好/更快的方法?如果是,请让我知道:
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();
是的,现在它看起来有点臃肿,但在这个线程中还有另一个简洁的答案,它的类型是of,所以我不会重复它
甚至
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,所以我不会重复它,我实际上建议如下:
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的计算基本上是一个类型强制转换,并且具有相同的性能特征,因此如果使用x is y{blah=Yx},则会执行两个强制转换,而不仅仅是as和null检查所需的一个强制转换。
通过使用interator,即yield-return,您不需要在内存中创建临时列表,将其转换为数组,然后返回数组。
还要注意where CaptureType:class。由于CaptureType是一个接口,您可以确保它始终通过,但使用as关键字需要该约束。如果您有一个所有插件都实现的基本接口,例如IPlugin,那么您可以用where CaptureType:IPlugin替换where CaptureType:class。我实际上建议如下:
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的计算基本上是一个类型强制转换,并且具有相同的性能特征,因此如果使用x is y{blah=Yx},则会执行两个强制转换,而不仅仅是as和null检查所需的一个强制转换。
通过使用interator,即yield-return,您不需要在内存中创建临时列表,将其转换为数组,然后返回数组。
还要注意where CaptureType:class。由于CaptureType是一个接口,您可以确保它始终通过,但使用as关键字需要该约束。如果您有一个所有插件都实现的基本接口,例如IPlugin,那么您可以用where CaptureType:IPlugin替换where CaptureType:class。我建议一个简单的
return Bot.AutoPlugins.Select (p => p.Interface).OfType<CaptureType> ().ToArray ();
编辑:
仔细想想,这可能比使用Where-then-Select组合的效率要低,就像在我的示例中,您对每个项目进行选择,然后按类型进行限制…我建议使用一个简单的
return Bot.AutoPlugins.Select (p => p.Interface).OfType<CaptureType> ().ToArray ();
编辑:
仔细想想,这可能比使用Where-then-Select组合的效率要低,就像我的示例中,您对每个项目进行选择,然后按类型进行限制…注意,您的第二个版本实际上返回一个插件数组,而不是CaptureType。您必须将其与调用Select相结合。@Dean Harding:是的,我看到了,但我打赌它也是合适的解决方案,并且在必要时-此数组将隐式转换。请注意,您的第二个版本实际上返回了一个插件数组,而不是CaptureType。您必须将其与Select调用相结合。@Dean Harding:是的,我看到了,但我打赌它也是合适的解决方案,并且在必要时-此数组将隐式强制转换。我不能使用as关键字,因为捕获类型将是一个接口,所以我不能使用where:类。。。但是谢谢你的输入我确实有一个接口,我所有的插件都实现了,是的,谢谢你。我不能使用as关键字,因为捕获类型将是一个接口,所以我不能使用where:class。。。但是谢谢你的输入我有一个接口,我所有的插件都实现了,是的,谢谢你。