2013-06-24 135 views
0

我試圖搜索特定的命名空間並返回實現指定接口並具有指定基類的所有類的實例。使用反射來實例化類

下面是代碼

private List<T> GetInstancesWithInterface<T, T2>(string @namespace) 
{ 
    var tList = Assembly.GetExecutingAssembly() 
         .GetTypes() 
         .Where(t => t.Namespace == @namespace) 
         .Where(t => t.BaseType == (typeof (T)) && t.GetInterfaces().Contains(typeof(T2))) 
         .Select(t => (T)Activator.CreateInstance(typeof(T), this)) 
         .ToList(); 
    return tList; 
} 

這裏是調用代碼

var examples = GetInstancesWithInterface<DrawableGameComponent, IResettable>("GamePhysics.Physics"); 

foreach (var example in examples) 
{ 
    Debug.Assert(example is IResettable); 
    var r = example as IResettable; 
    _examples.Add(r); 
    Components.Add(example); 
    if (Components.Count == 0) continue; 
    example.Enabled = false; 
    example.Visible = false; 
} 

我遇到的問題是,因爲我回來,不能被視爲的DrawableGameComponent列表中斷言失敗IResettable所以代碼var r = example as IResettable總是返回null。

其他信息

我應該也提到DrawableGameComponent沒有實現IResettable接口。我試圖獲取的所有三個示例類都有DrawableGameComponent作爲基類,它們也實現了IResettable

更多的想法

我在想,也許我應該創建一個名爲Example它實現DrawableGameComponentIResettable,然後我的具體實例類可以直接實現Example基類一個新的抽象類。我想這可能是更好的設計,但我也有興趣知道,如果我可以得到它的工作。

+0

「因爲我找回了一個不能被視爲IResettable的DrawableGameComponent的列表」 - 我非常懷疑這是問題所在。'is'運營商應該很好地處理這種情況。你是否已經用調試器遍歷它並查看每個返回的對象? –

+0

是的,我已經通過了,r始終爲空。我應該也提到'DrawableGameComponent'沒有實現IResettable接口。我試圖獲取的三個示例類都有DrawableGameComponent作爲基類,它們也實現了IResettable。我會用這個額外的信息更新這個問題。 – Steve

+0

你試過'(typeof(T))。IsAssignableFrom(t.BaseType)'(反之亦然)而不是'如果你正在尋找'T'的子類,那麼'=='很可能不起作用。 – valverij

回答

3

(張貼在意見中的要求非常感謝你等着。)

看看在Select部分的LINQ查詢:

.Select(t => (T)Activator.CreateInstance(typeof(T), this)) 

傳遞typeof(T)Activator.CreateInstance將創建一個新的對象鍵入T。因爲實際上尋找創造出你發現的類型的對象,你想這個更改爲:

.Select(t => (T)Activator.CreateInstance(t, this)) 

這將確保激活創建在以前Where找到的類型的實例。

李還提到,在Where表達使用類似IsSubclassOfIsAssignableFrom子類搜索時最好直線上升==。從我的經驗來看,他們的工作大致相同,只有IsAssignableFrom也可以與接口一起工作。

4

你傳遞了​​錯誤的類型Activator.CreateInstance,你應該將其更改爲:

.Select(t => (T)Activator.CreateInstance(t, this)) 

你可能也想在你Where條款,而不是在基類直視使用Type.IsSubclassOf

+0

謝謝李。 @valverij已經在他的評論中回答了,所以我會等待看他是否發佈了我能接受的答案。 – Steve

+1

感謝您提供關於'IsSubclassOf'的更多信息,我可以看到這會更好。 – Steve

相關問題