从字符串.Net C#获取完全限定的类型名称

时间:2010-08-28 22:16:02

标签: c# .net

我有一个字符串,如“Int”,“Double”,“DateTime”等。如何从此字符串中获取完全限定名称?

4 个答案:

答案 0 :(得分:6)

值得注意的是int不是一种类型。它是C#为类型System.Int32提供的别名。考虑到这一点,并假设您只关心核心类型,您可以尝试:

var typeName = "DateTime";

var systemTypesAssembly = Assembly.Load("mscorlib");

var type = (from t in systemTypesAssembly.GetTypes()
           where t.Name == typeName
           select t).FirstOrDefault();

Console.WriteLine(type.FullName);

正如我所说, 不会适用于Int,但适用于Int32这是其别名的类型。 此代码也不包含错误处理,例如,在mscorlib中找不到与您在typeName

中输入的类型相匹配的类型

答案 1 :(得分:2)

在进一步讨论之前,我想指出.NET Framework基类库中没有名为Int的类。有System.Int32,C#中碰巧有别名:int

你可以通过以下几种方式做到这一点。

一种简单但有限的方法是将字符串映射到相应的FQN:

public static IDictionary<string, string> FqnMap = new Dictionary<string, string>
{
    { "Int", "System.Int32" },
    { "Double", "System.Double" },
    { "DateTime", "System.DateTime" },
};

public string GetFqn(string name)
{
    return FqnMap[name]; // TODO: add error handling
}

更复杂但更强大的方法是使用reflection从一组程序集中搜索所有类型。像这样:

public class FqnResolver
{
    public FqnResolver(IEnumerable<Assembly> assemblies)
    {
        Assemblies = new List<Assembly>(assemblies);
    }
    public FqnResolver(params Assembly[] assemblies) : this(assemblies as IEnumerable<Assembly>) { }
    public FqnResolver() : this(new Assembly[0]) { }

    public ICollection<Assembly> Assemblies { get; private set; }

    public string GetFqn(string name)
    {
        var candidates = from a in Assemblies
                         from t in a.GetTypes()
                         where t.Name == name
                         select t.FullName;
        return candidates.First(); // will throw if no valid type was found
                                   // and does not count duplicates
    }
}

答案 2 :(得分:0)

这在.Net中并不是真正有效的方式。要获得类型的完全限定名称,您需要使用Type对象。为了获得Type对象,您通常需要一个实例,完全限定名称,或者您需要进行一些搜索。

后者有效,但效率不高,因为您需要搜索每个程序集并键入已加载的AppDomain以找到正确的答案。

foreach ( var assembly in AppDommain.CurrentDomain.GetAssemblies() ) {
  foreach ( var type in assembly.GetTypes() ) {
    if ( type.Name == target ) {
      return type.FullName;
    }
  }
}

此解决方案仍然不会100%为您工作。主要是因为.Net框架中没有类型“Int”。它的实际类型名称是“Int32”。

答案 3 :(得分:0)

类似“String”的类型名称可能不明确,因为它可能引用System.StringFooAssembly.String,因此您必须搜索所有已加载程序集中的所有类型,这可能会产生多个结果。这一点反射可能会很慢,但是您可以以牺牲内存为代价来明显优化缓存结果:

static void Main(string[] args)
{
    string typeName = "String";
    foreach (var type in GetFullType(typeName))
    {
        Console.WriteLine(type.FullName);
    }
}

static IEnumerable<Type> GetFullType(string className)
{
    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
        foreach (var type in assembly.GetTypes())
        {
            if (type.Name.Equals(className, StringComparison.OrdinalIgnoreCase))
            {
                yield return type;
            }
        }
    }
}