如何获取程序集的命名空间?

41

假设我有一个程序集(类库dll),我使用以下代码加载它:

Assembly a = Assembly.LoadFrom(@"C:\Documents and Settings\E454935\My Documents\Visual Studio 2005\Projects\nunit_dll_hutt\for_hutt_proj\bin\Debug\asdf.dll");   

我需要获取程序集的类型。为了获取类型,我需要程序集的命名空间。

Type t = asm.GetType("NAMESPACE.CLASSNAME",false,true);             

如何在上面的行中获取命名空间?因为要获取命名空间,需要先获取类型。

Type.Namespace;

我需要获取程序集的命名空间,以便获取其类型。谢谢。
8个回答

38

使用

Assembly.GetTypes();
这将为您获取所有类型的集合,然后您可以为每个类型获取其Namespace属性。 然后,我想您只需检查所有类型是否具有相同的Namespace值,并使用此值。否则,请添加其他逻辑以检测要考虑哪个命名空间为主要命名空间。

25
一个程序集可以包含多个命名空间。我认为你真正想问的是如何在不指定命名空间的情况下从程序集中获取类型。
我不知道是否有更好的方法,但你可以尝试像这样查找特定类型(添加-使用linq;):
myassembly.GetTypes().SingleOrDefault(t => t.Name == "ClassName")

如果同名类在不同的命名空间下有多个(因为Single方法确保了只有一个),那么这将有效地引发异常。

要获取该类的命名空间列表,您可以:

Assembly.Load("ClassName").GetTypes().Select(t => t.Namespace).Distinct();

此外,一个程序集甚至可以在同一命名空间中包含多个类型。OP 需要理解这个概念。 - Cerebrus
谢谢,这个答案更好。 - Najeeb

23

更新:

如果你的项目中程序集名称程序集命名空间,并且你确定保持它们相同你想要获取当前执行程序集的命名空间,那么你可以使用以下代码:

var namespace = Assembly.GetExecutingAssembly().GetName().Name;

至于您加载的程序集:

var namespace = myAssembly.GetName().Name;

但是,如果您的项目中程序集名称程序集命名空间不同,则可以使用以下方式:

// Like @eglasius answer >>
// Find all namespaces in the target assembly where a class with the following name is exists:
var namespaceList=Assembly.Load("MyClassName").GetTypes().Select(t => t.Namespace).Distinct();

1
程序集名称并不等同于程序集的命名空间,或者该程序集中任何特定类型的命名空间。因此,很遗憾,这个答案是错误的。 - ErikE
3
谢谢您的提示,我知道这个问题已经有答案了,我的回答只是针对这种情况的一种次要方式:默认情况下它们是相等的,在某些情况下开发人员会保持它们相同,所以在这些情况下我的答案是正确的。我用一个额外的 IF 条件更新了我的答案。 - Ramin Bateni

1

给定一个程序集应至少包含一个类型,并且每个类型都位于程序集命名空间中,其中最短的一个将成为程序集命名空间。

public string GetAssemblyNamespace(Assembly asm)
{
    string ns = "";

    foreach (Type tp in asm.Modules.First().GetTypes())
    {
        if (ns.Length == 0 || tp.Namespace.Length < ns.Length)
            ns = tp.Namespace;
    }

    return ns;
}

1
使用Mono/Xamarin时,您无法访问“NameSpace”属性。您可以改用以下内容:
var str = typeof(ATypeInTheAssembly).AssemblyQualifiedName;
return str.Split(',')[1].Trim();

0

只需要使用以下代码来获取命名空间:

  var assembly = System.Reflection.Assembly.GetAssembly(this.GetType());//Get the assembly object
  var nameSpace = assembly.GetType().Namespace;//Get the namespace

或者

public string GetNamespace(object obj)
{
    var nameSpace = obj.GetType().Namespace;//Get the namespace

    return nameSpace;
}

2
这个答案显然是错误的。assembly.GetType() 返回一个 System.Reflection.RuntimeAssembly 对象,该类的命名空间显然始终为 System.Reflection - Bitterblue
@Bitterblue 第一段代码在某个时候帮助了我,但我不记得是什么应用。只要我找到我使用该代码的地方,我会添加更多细节。 - Tiago S

0

Assembly.GetName().Name 可以获取默认命名空间。


这不是用户定义的元数据吗?那么它可以是任何东西。 - Ray
6
不,这是文件的名称。它不一定与命名空间有任何关系。 - Mark A. Donohoe
2
这是文件的名称。它不一定与命名空间有任何关系。 - Gianpiero

-1
Private Function GetRootNamespace() As String
    Try
        Dim xDeclaringTypeFullName As String = Assembly.GetEntryAssembly.EntryPoint.DeclaringType.FullName
        Dim xRootNamespace As String = xDeclaringTypeFullName.Substring(0, xDeclaringTypeFullName.IndexOf("."))

        Return xRootNamespace
    Catch ex As Exception
        Return String.Empty
    End Try
End Function

1
感谢您对Stack Overflow社区做出贡献的兴趣。这个问题已经有很多答案了,其中一个答案已经得到社区的广泛验证。您确定您的方法之前没有被提到过吗?如果是这样的话,能否解释一下您的方法与之前的方法有何不同,以及在什么情况下您的方法可能更好,并且为什么您认为之前的答案不够满意。您能否编辑您的答案并提供解释? - undefined
1
此外,这个问题是关于C#的,但是您却用VB回答了。这并没有回答到所提出的问题。 - undefined

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