【问题标题】:How to check if string is a namespace如何检查字符串是否是命名空间
【发布时间】:2011-02-06 01:44:10
【问题描述】:

我有一个字符串,我想检查它是否代表正确的命名空间,例如。 System.IO 可以,但System.Lol 不行。

我想应该使用一些反射,但我想不通。

有什么想法吗?

【问题讨论】:

    标签: c# .net namespaces


    【解决方案1】:

    CLR 并没有真正的“命名空间”概念:它们实际上只不过是一种命名约定。因此没有 API 可以“列出命名空间”或“获取命名空间”甚至“获取此命名空间中的所有类型”。

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

    【讨论】:

      【解决方案2】:

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

      • 枚举所有类型(你不指定源集,比如说.NET Framework,那么你需要包括所有默认的.NET程序集(查看VS在创建项目时引用的那些),或者你的自定义程序集,然后在程序集中键入)。
      • 在给定类型上查找命名空间属性

      你需要使用什么:

      Assembly.Load method

      Assembly.GetTypes method

      Type.Namespace property

      【讨论】:

        【解决方案3】:

        你能做到吗?

        Assembly asm = Assembly.GetExecutingAssembly();
        List<string> namespaceList = new List<string>();
        
        foreach (Type type in asm.GetTypes())
        {
            namespaceList.Add(type.Namespace);
        }
        

        然后只检查字符串是否在列表中?

        (请注意,这不是经过测试的代码!)

        【讨论】:

          【解决方案4】:

          试试这个方法:

          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 在哪里:

          类型或命名空间名称“name”确实 在类或命名空间中不存在 “范围”(您是否缺少程序集 参考?)

          自定义引用添加:

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

          【讨论】:

            【解决方案5】:

            您的问题“如何检查字符串是否为名称空间”仅在您考虑 where 您正在检查名称空间时才有效。

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

            一旦您决定了准备查看哪些程序集,您就可以遍历它们以确定是否存在特定的命名空间,如下所示:

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

            【讨论】:

            • 顺便说一句,你不能使用保留关键字namespace作为变量名;)
            • 为了正确起见,你应该@-ize命名空间参数,命名空间是一个C#关键字:)
            • 哦,太挑剔了!我很确定答案是清晰的,但编辑是你的。 :)
            • return assemblies.SelectMany(a =&gt; a.GetTypes()).Any(t =&gt; t.Namespace == ns)
            猜你喜欢
            • 2011-11-25
            • 2012-03-23
            • 2015-06-12
            • 2011-03-15
            • 2015-10-29
            • 2013-03-07
            相关资源
            最近更新 更多