2009-08-25 72 views
1

是否有可能用Select()或其他東西替換方法ForEach()或其他東西來寫入下一個代碼在一個字符串嵌套擴展方法?或者也許有另外一種方法來改進算法?用適當替換嵌套的ForEach

var list = new List<IStatementParser>(); 

System.IO.Directory.GetFiles(path, "*.dll") 
    .ForEach(f => System.Reflection.Assembly.LoadFrom(f) 
     .GetTypes() 
     .Where(t => !t.IsInterface && typeof(IFoo).IsAssignableFrom(t)) 
     .ForEach(t => list.Add((IFoo)Activator.CreateInstance(t)))); 

return list.ToDictionary(k => k.Name, v => v.GetType()); 

它加載來自組件的所有類的path實現IFoo並將它們添加到Dictionary<string, Type>其中字符串是IFoo.Name

回答

3
var foos = 
    from dllFile in Directory.GetFiles(path, "*.dll") 
    from type in Assembly.LoadFrom(dllFile).GetTypes() 
    where !type.IsInterface && typeof(IFoo).IsAssignableFrom(type) 
    select (IFoo) Activator.CreateInstance(type); 

return foos.ToDictionary(foo => foo.Name, foo => foo.GetType()); 
+1

您需要一個foo => foo.GetType()參數作爲ToDictionary調用中的值委託。否則,一個很好的答案。 – 2009-08-26 02:31:46

+0

我只需要澄清'let'的用法,我已準備好接受您的答案。和btw,我不需要Dictionary ,我需要Dictionary where Type = IFoo(我編輯了初始文章) - 因爲這個字典將被FooFactory用來創建IFoo的一個實例。請求,在當前會話中可能根本不會發生。 – abatishchev 2009-08-26 09:12:55

+0

編輯爲包含.GetType()調用。 @Pavel的答案中的let子句是一種風格的東西 - 你不需要擁有它,但他可能認爲它更清晰。 – 2009-08-26 14:58:58

3

我看不出有任何需要中間List在這裏所有的 - 你可以這樣做這樣的:

return (from dll in Directory.GetFiles(path, "*.dll") 
     let asm = Assembly.LoadFrom(dll) 
     from t in asm.GetTypes() 
     where !t.IsInterface && typeof(IFoo).IsAssignableFrom(t) 
     select (IFoo)Activator.CreateInstance(t) 
     ).ToDictionary(foo => foo.Name, foo => foo.GetType()) 

順便說一句,你可能還需要檢查類型是否abstract試圖實例之前。

+0

您能否介紹一下您使用'let'的方法?下面的Bryan Watts不是 – abatishchev 2009-08-26 09:00:06

+0

這是一個方便/可讀性的東西,不是絕對必要的。 – 2009-08-26 16:17:16