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

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

值得记住的是, 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 ,它是别名的类型。 此代码也不包含error handling,例如,在mscorlib中找不到与您在typeName输入的类型匹配的类型

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

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

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

 public static IDictionary FqnMap = new Dictionary { { "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 assemblies) { Assemblies = new List(assemblies); } public FqnResolver(params Assembly[] assemblies) : this(assemblies as IEnumerable) { } public FqnResolver() : this(new Assembly[0]) { } public ICollection 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 } } 

这在.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”。

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

 static void Main(string[] args) { string typeName = "String"; foreach (var type in GetFullType(typeName)) { Console.WriteLine(type.FullName); } } static IEnumerable 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; } } } }