【问题标题】:Avoid giving namespace name in Type.GetType()避免在 Type.GetType() 中给出命名空间名称
【发布时间】:2012-03-05 15:05:16
【问题描述】:
Type.GetType("TheClass");

如果namespace 不存在,则返回null,例如:

Type.GetType("SomeNamespace.TheClass"); // returns a Type object 

有什么办法可以避免给namespace这个名字?

【问题讨论】:

  • 您是否意识到在一个添加了许多引用并且您尝试解析类型的文件有许多 using 语句的项目中可以有多个不同的类,称为 TheClass?您应该传递包含名称空间的完全限定名称,就像您在编写名字和姓氏的文档中引用自己时一样。如果存在许多 TheClass 类,编译器应该使用哪一个?命名空间告诉哪个。
  • 我会抛出 ArgumentException 而不是仅仅返回 null。没有Namespace,你无法分辨

标签: c# c#-4.0 reflection types


【解决方案1】:

这是方法期望得到的参数,所以不是。你不能。

typeName:由其命名空间限定的类型名称。

MSDN

您希望如何区分名称相同但命名空间不同的两个类?

namespace one
{
    public class TheClass
    {
    }
}

namespace two
{
    public class TheClass
    {
    }
}

Type.GetType("TheClass") // Which?!

【讨论】:

  • @NIleshLanke,我希望你意识到微软没有根据你的需求设计 .NET 框架,但它的架构是为了在更广泛的场景中使用。例如,您在两个不同的命名空间中有相同的类名。
  • @gdoron,为什么在这篇文章中坚持认为不可能,但接受的答案表明它可以?
  • @gdoron,不,你没有。上面的答案从字面上向您展示了如何做到这一点。
  • @gdoron,您需要查看用户实际追求的内容,而不仅仅是问题标题的字面意思。就像我问我是否可以喝西瓜而你只是回答“你不能”,但随后 Fr33dan 出现并说“如果你把它切成小方块并把它扔进 Nutribullet 就可以” - 这就是我实际上后。我认为可以肯定地说,在这种情况下,用户只是想要某种方式来获取类型,而不必指定命名空间。
  • @gdoron,阅读此stackoverflow.com/help/how-to-answer,尤其是关于“回答问题”的部分
【解决方案2】:

我使用了一个辅助方法,它在所有加载的Assemblys 中搜索与指定名称匹配的Type。尽管在我的代码中只有一个 Type 结果,但它支持多个。我验证每次使用时只返回一个结果,并建议您也这样做。

/// <summary>
/// Gets a all Type instances matching the specified class name with just non-namespace qualified class name.
/// </summary>
/// <param name="className">Name of the class sought.</param>
/// <returns>Types that have the class name specified. They may not be in the same namespace.</returns>
public static Type[] getTypeByName(string className)
{
    List<Type> returnVal = new List<Type>();

    foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
    {
        Type[] assemblyTypes = a.GetTypes();
        for (int j = 0; j < assemblyTypes.Length; j++)
        {
            if (assemblyTypes[j].Name == className)
            {
                returnVal.Add(assemblyTypes[j]);
            }
        }
    }

    return returnVal.ToArray();
}

【讨论】:

  • +1 用于回答问题,而不是在上面的火焰战争中堆积。
  • 另一个答案来自知道而不是不使用 no namespace bla bla :) ty for answer
  • 太棒了,照它说的做。我要添加的主要内容是使用 assemblyTypes[j].Name.EqualsIgnoreCase(className)。
【解决方案3】:

没有必要把事情复杂化。

AppDomain.CurrentDomain
    .GetAssemblies()
    .SelectMany(x => x.GetTypes())
    .FirstOrDefault(t => t.Name == "MyTypeName");

使用Where 而不是FirstOrDefault 来获取所有结果。

【讨论】:

    【解决方案4】:

    简单缓存版

    执行一次....

            nameTypeLookup = typeof(AnyTypeWithin_SomeNamespace).Assembly
                .DefinedTypes.Where(t => t.DeclaringType == null)
                .ToDictionary(k => k.Name, v => v);
    

    用法-通过字典多次查找

    nameTypeLookup["TheClass"];
    

    【讨论】:

    • 这是优雅且可重复使用的,与其他答案相比,它最能满足我的使用需求(这也可以工作)。不知道为什么你投了反对票,因为如果你想通过它们的短名称而不是相当长的 AssemblyQualifiedName 加载类型,并且你想通过锚定在你自己的特定程序集中范围内,这 a) 有效并且 b) 是优雅/简单/简洁的到不会消失的已知类型,例如 ORM/EM 中的主表/实体。
    • 另外,在我实现你的答案时,我可以说this.GetType().Assembly... 而不使用其他类型,因为我的类通过短名称引用其他类与目标类在同一个程序集中. return this.GetType().Assembly.DefinedTypes.First(t =&gt; t.Name == ClassName);
    猜你喜欢
    • 1970-01-01
    • 2011-05-14
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    相关资源
    最近更新 更多