2010-04-09 15 views

risposta

4

La tua domanda "Come verificare se la stringa è un namespace" è valida solo se si considera dove si sta verificando per spazi dei nomi.

Gli spazi dei nomi sono prefissi ai nomi delle classi e le classi sono associate a un assieme. Per verificare se esiste uno spazio dei nomi, è necessario decidere quali gruppi sono pronti a esaminare per trovare l'esistenza dello spazio dei nomi.

Una volta deciso che le assemblee si sono preparati a guardare attraverso, si può scorrere attraverso di loro per l'esistenza di un particolare spazio dei nomi in questo modo:

public bool NamespaceExists(IEnumerable<Assembly> assemblies, string ns) 
{ 
    foreach(Assembly assembly in assemblies) 
    { 
     if(assembly.GetTypes().Any(type => type.Namespace == ns)) 
      return true; 
    } 

    return false; 
} 
+0

Btw, non è possibile utilizzare riservato parola chiave 'namespace' come nome di variabile;) – abatishchev

+0

Solo per motivi di correttezza, dovresti @ -izzare il parametro namespace, namespace è una parola chiave C# :) – Marek

+1

Oh, così schizzinoso! Sono abbastanza sicuro che la risposta sia leggibile senza, ma una modifica è tua. :) –

0

Il CLR non ha realmente un concetto di "namespace": sono davvero poco più di una convenzione di denominazione. Quindi non ci sono API per "elencare spazi dei nomi" o "ottenere spazi dei nomi" o anche "ottenere tutti i tipi in questo spazio dei nomi".

Il meglio che si può fare è passare in rassegna tutti gli assembly caricati, quindi eseguire il ciclo di tutti i tipi esportati in ciascuno di questi assembly e verificare se la stringa data è un "prefisso" su uno qualsiasi di questi nomi di tipi. Immagino che questa soluzione non sarebbe la più veloce del mondo, ma non sarebbe nemmeno totalmente inattuabile.

-2

Non c'è riflessione sui namespace. Gli spazi dei nomi definiscono il nome completo del tipo. Quindi quello che dovete fare è:

  • enumerare tutti i tipi (non si specifica il set di fonte, diciamo .NET Framework, allora avete bisogno di includere tutti i gruppi di default .NET (vedi quelli a cui fa riferimento VS quando si crea un progetto) o il proprio assieme personalizzato, quindi digita nell'assieme).
  • Cercare proprietà Namespace del tipo data

Quello che è necessario utilizzare:

Assembly.Load method

Assembly.GetTypes method

Type.Namespace property

2

Puoi fare questo?

Assembly asm = Assembly.GetExecutingAssembly(); 
List<string> namespaceList = new List<string>(); 

foreach (Type type in asm.GetTypes()) 
{ 
    namespaceList.Add(type.Namespace); 
} 

Quindi controllare per vedere se la stringa è presente nell'elenco?

(Attenzione, questo non testati codice!)

8

Prova questo approccio:

using System.CodeDom.Compiler; 
using System.Linq; 

class NamespaceTester : IDisposable 
{ 
    private CodeDomProvider provider = CodeDomProvider.CreateProvider("c#"); 
    private CompilerParameters settings = new CompilerParameters(); 
    private CompilerResults results; 

    public bool Test(string[] namespaces) 
    { 
     results = provider.CompileAssemblyFromSource(
      settings, 
      namespaces.Select(n => String.Format("using {0};", n)).ToArray()); 
     return results.Errors 
      .OfType<CompilerError>() 
      .Any(e => String.Equals(
       e.ErrorText, 
       "CS0234", 
       StringComparison.Ordinal)); 
    } 

    public void Dispose() 
    { 
     if (results != null) 
     { 
      System.IO.File.Delete(results.CompiledAssembly.Location); 
     } 
    } 
} 

dove CS0234 è:

Il tipo o dello spazio dei nomi il nome 'name' fa non esiste nella classe o nel namespace 'scope' (ti manca un riferimento ?)

riferimenti personalizzati aggiungendo:

settings.ReferencedAssemblies.Add("Foobar.dll") 

Usage:

public static void Main(string[] args) 
{ 
    using (var tester = new NamespaceTester()) 
    { 
     var success = tester.Test(new[] { 
      "System.IO", 
      "System.LOL" 
     }); 
    } 
} 
+0

+1 per divertimento – Marek

Problemi correlati