如何检查字符串是否为命名空间

8

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

我猜需要使用一些反射,但我无法理解。

你有什么想法吗?

5个回答

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 表示:

'scope' 中不存在 '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"
        });
    }
}

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

顺便提一下,你不能使用保留关键字 "namespace" 作为变量名;) - abatishchev
为了正确起见,你应该在命名空间参数上加上@符号,因为namespace是C#的关键字 :) - Marek
1
哦,这么挑剔!我非常确定答案是清晰易懂的,但编辑权在你手中。 :) - Paul Turner
2
return assemblies.SelectMany(a => a.GetTypes()).Any(t => t.Namespace == ns) - abatishchev

2

你能做到这个吗?

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

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

那么只需要检查字符串是否在列表中即可吗?
(请注意,这不是经过测试的代码!)

0

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

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


-1

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

  • 枚举所有类型(您未指定源集,假设为.NET Framework,则需要包括所有默认的.NET程序集(创建项目时VS引用的那些程序集),或者您的自定义程序集,然后是程序集中的类型)。
  • 查找给定类型的Namespace属性

你需要使用的方法:

Assembly.Load方法

Assembly.GetTypes方法

Type.Namespace属性


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接