2014-05-19 63 views
12

Getting all types that implement an interface相關我們可以很容易地獲得Assembly中實現特定接口的所有類型。獲取所有首先實現接口但沒有派生類的c#類型

例子:

interface IFace 
{ 
} 

class Face : IFace 
{ 
} 

class TwoFace : Face 
{ 
} 

對於這個結構,我們會發現通過反射都類,即從第一實施過派生的所有類,使用

GetTypes().Where(
    type => type.GetInterfaces().Contains(typeof(IFace)) 
) 

所以問題是:如何限制結果到最初實現接口的基類? 在這個例子中:只有班級類型是相關的。

+0

注意:迭代所有找到的類/類型,檢查是否從另一個派生出來似乎不實際,對我無效 –

+0

這是使用反射的限制。一個接口不知道哪些類實現它,所以如果不迭代所有內容,就無法得到它們。如果你想要更好的表現,你可能需要Roslyn。 –

+3

@ childno.de一旦你已經在程序集中迭代所有類型,它不會有任何額外的性能影響,只是檢查它的繼承 –

回答

13

首先,我會使用Type.IsAssignableFrom而非GetInterfaces,但那麼所有你需要做的是排除類型的父類是已經在集:

var allClasses = types.Where(type => typeof(IFace).IsAssignableFrom(type)) 
         .ToList(); // Or use a HashSet, for better Contains perf. 
var firstImplementations = allClasses 
     .Except(allClasses.Where(t => allClasses.Contains(t.BaseType))); 

或在評論中指出,等效:

var firstImplementations = allClasses.Where(t => !allClasses.Contains(t.BaseType)); 

注意,這將不返回從它實現一個接口的類派生的類,但重新實現它。

+1

爲什麼不只是'allClasses.Where(t =>!allClasses.Contains(t.BaseType))'? –

+0

@BenAaronson:'除外'通常更有效率,就這些。但是,是的,它們基本上是相同的。 –

+0

這是?這感覺就像它想要一個自己的問題! –

相關問題