2010-09-07 22 views
11

Czy istnieje sposób na uzyskanie zestawu zawierającego klasę o nazwie TestClass? Po prostu znam nazwę klasy, więc nie mogę utworzyć takiej instancji. IPobierz zestaw według nazwy klasy

Type objectType = assembly.GetType("TestClass"); 

nie działa dla mnie.

+3

Powtórzenie wszystkich zestawów referencyjnych byłoby Twoją jedyną opcją, ale z łatwością wygenerowałoby duplikaty. Ale nie do końca wierzę, że to wszystkie informacje, które posiadasz, więc powinieneś wypróbować i wyjaśnić swoje uzasadnienie swojego pytania. –

Odpowiedz

16

Z Type objectType w pytaniu, zakładam, że jesteś faktycznie po typu przez nazwę (nie montażowy); tak zakładając zespół jest załadowany i nazwa typu jest wyjątkowy, LINQ może pomóc:

Type objectType = (from asm in AppDomain.CurrentDomain.GetAssemblies() 
        from type in asm.GetTypes() 
        where type.IsClass && type.Name == "TestClass" 
        select type).Single(); 
object obj = Activator.CreateInstance(objectType); 

Jednak może lepiej pracować z nazwą zespołu wykwalifikowanych zamiast nazwy typu.

+0

Nie można załadować jednego lub więcej żądanych typów. Pobierz właściwość LoaderExceptions, aby uzyskać więcej informacji. – Soonts

+1

@Soonts - brzmi jak być może brakuje zależności w złożeniu? –

21
Assembly asm = typeof(TestClass).Assembly; 

dostanie zespół, o ile jest on przywoływany. W przeciwnym razie trzeba by użyć pełnej nazwy:

Assembly asm = null; 
Type type = Type.GetType("TestNamespace.TestClass, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); 
if (type != null) 
{ 
    asm = type.Assembly; 
} 
3

Właściwie znajomość nazwy klasy jest wystarczająca w większości scenariuszy. MSDN mówi - Jeśli typ znajduje się w aktualnie wykonywanym złożeniu lub w Mscorlib.dll, wystarczy podać nazwę typu kwalifikowaną według jej przestrzeni nazw.

Type neededType = Type.GetType("TestClass"); //or typeof(TestClass) 
Assembly a = neededType.Assembly; 

W przypadku, gdy nie wiem, rodzaj montażu zawierający (choć nie mogę sobie wyobrazić, dlaczego) -

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
Asssembly result = assemblies.FirstOrDefault(a=>a.GetType("TestClass",false)!=null); 

Jedynym ograniczeniem - montaż zawierające TestClass powinny były już załadowane w momencie wywołania takiego kodu .

Mam nadzieję, że to pomoże. :) Odpowiedź

2

Marca jest naprawdę dobre, ale ponieważ był zbyt powolny (używam tej metody często), zdecydowałem się iść z innym podejściem:

private static Dictionary<string, Type> types; 
    private static readonly object GeneralLock = new object(); 

    public static Type FindType(string typeName) 
    { 
     if (types == null) 
     { 
      lock (GeneralLock) 
      { 
       if (types == null) 
       { 
        types = new Dictionary<string, Type>(); 
        var appAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
        foreach (var appAssembly in appAssemblies) 
        { 
         foreach (var type in appAssembly.GetTypes()) 
          if (!types.ContainsKey(type.Name)) 
           types.Add(type.Name, type); 
        } 
       } 
      } 
     } 

     return types[typeName]; 
    } 

można obsługiwać nazwy zderzenie tak jak chcesz, ale w tym przykładzie postanowiłem po prostu zignorować kolejne.

Powiązane problemy