我有一个字符串,如“Int”,“Double”,“DateTime”等。如何从此字符串中获取完全限定名称?
答案 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.String
或FooAssembly.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;
}
}
}
}