从字符串.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.String
或FooAssembly.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; } } } }