2012-07-31 68 views
1

我正在使用外部DLL,它具有抽象基類Packet和子類。在知道C#中部分類名時動態創建對象

子類以它們表示的數字命名,一個名稱可能是P132_RandomString。我正在解析一個包含這些數字的文件,並且爲每個我想要創建相應對象的數字。有幾百個不同的子類,DLL沒有工廠方法(至少不是我的輸入)。

問題是我不知道「RandomString」部分,如果我做了我可以使用反射,但我認爲沒有辦法使用反射,因爲我只知道類名的開始?

我能想到的是實現我自己的工廠方法與數百個case語句的唯一的解決辦法,但這種感覺有點麻煩......

我的問題是:有沒有一個很好的辦法做到這一點?

回答

2

您可以使用LINQ Where子句來獲取所需的類型。 考慮下面的程序: (這是假設你知道的基類和前綴)

class Program { 
    static void Main(string[] args) { 

     string prefix = "p22"; 
     IEnumerable<Type> types = Assembly.LoadFrom("c:\\Sample.Assembly.dll").GetTypes();  
     Type baseClass = typeof(foo); 
     Type foundType = types.Where(
      t => t.Name.StartsWith(prefix) && 
       t.IsSubclassOf(baseClass) 
       ).SingleOrDefault(); 
     foo myClass = (foo)Activator.CreateInstance(foundType); 
       //Do Stuff with myClass 
    } 
} 
abstract class foo { } 
class p22_notMyClass { } 
class p22_myclass : foo { } 
} 
+0

謝謝你的回答。我不得不使用Assembly.LoadFrom來加載程序集文件,但除了那個foundType得到空,除非我刪除t.IsSubClassOf(baseClass)這是奇怪的...一旦我刪除,我得到正確的類型,但後來我不能轉換爲抽象類foo「InvalidCastException」。 – HischT 2012-08-01 08:53:07

+0

更新:現在它使用Assembly.LoadFrom,它不起作用的原因是我引用了DLL的副本......並且我得到了不同的上下文。 *嘆* – HischT 2012-08-01 10:03:25

0

要加載從組件的所有類型使用Assembly.GetTypes

var objects = new List<Object>(); 
Assembly SampleAssembly; 
SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll"); 
// Obtain a reference to types known to exist in assembly. 
Type[] types = SampleAssembly.GetTypes(); 
foreach(Type t in types) 
    if(t.Name.StartsWith("P132") 
     objects.Add(Activator.CreateInstance(t)); 

使用Activator.CreateInstance方法描述here

0

使用Assembly.GetTypes +上Type.FullName + Activator.CreateInstance()一些String.IndexOf(或其它匹配)。

0

可以使用Assembly.GetTypes()方法和迭代的類型,並找出哪些類在其名稱中的數字。然後你可以使用Activator.CreateInstance來獲得一個實例。