2010-04-09 31 views
8

我有一个字符串,我想检查它是否代表一个适当的命名空间,例如。 System.IO是好的,但System.Lol不是。如何检查字符串是否为命名空间

我想应该使用一些反射,但我无法弄清楚这一点。

有什么想法?

回答

4

你的问题“如何检查是否字符串是一个命名空间”是唯一有效的,当你考虑其中你检查命名空间。

命名空间是类名的前缀,类的作用域是一个程序集。要检查名称空间是否存在,您需要决定准备查看哪些程序集以查找命名空间的存在。

一旦你决定哪些程序集你准备一下通过,你可以遍历它们特定名称空间的存在,像这样:

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

顺便说一句,你不能使用保留关键字'namespace'作为变量名;) – abatishchev 2010-04-09 10:32:15

+0

只是为了正确性,你应该使用@ -ize命名空间参数,namespace是一个C#关键字:) – Marek 2010-04-09 10:32:45

+1

哦,太挑剔了!我很肯定没有,答案是清晰的,但编辑是你的。 :) – 2010-04-09 11:44:04

0

CLR并没有真正具有“命名空间”的概念:它们实际上不过是命名约定。所以没有API来“列出命名空间”或“获取命名空间”,甚至“获得这个命名空间中的所有类型”。

您可以做的最好的方法是遍历所有已加载的程序集,然后遍历每个程序集中的所有导出类型,并检查给定的字符串是否是任何这些类型名称的“前缀”。我想这个解决方案不会是世界上最快的,但它也不会完全不可行。

-2

命名空间没有反映。名称空间定义完整的类型名称。所以你需要做的是:

  • 枚举所有类型(你不指定源集,让我们说,.NET框架,那么你需要包括所有的默认.NET程序集(看看由VS引用的那些)当你创建一个项目时)或你的自定义程序集,然后输入程序集)。
  • 查找Namespace属性给定类型

你需要使用什么:

Assembly.Load method

Assembly.GetTypes method

Type.Namespace property

2

你能做到这一点?

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

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

然后只是检查一下,看看字符串是否在列表中?

(被警告,这是没有经过测试的代码!)

8

试试这个办法:

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); 
     } 
    } 
} 

其中CS0234是:

类型或命名空间名称 '名' 呢 不存在于类或名称空间 '范围'(您是否缺少程序集 参考?)

定制引用加:

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

用法:

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

+1为了娱乐 – Marek 2010-04-09 10:34:57

相关问题