简体   繁体   中英

Getting a fully qualified type name from a string .Net C#

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

It's worth bearing in mind that int isn't a type. It's an alias provided by C# for the type System.Int32 . Bearing that in mind, and assuming you only care about core types, you can try:

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);

As I said, this will not work for Int , but would work for Int32 which is the type it's aliased to. This code also contains no error handling for where, for example, no type is found in mscorlib that matches the one you've entered in typeName

Before I go any further, I'd like to point that there is no class in the .NET Framework base class library named Int . There is System.Int32 , that in C# happens to have an alias: int .

You can do this several ways.

A simple but limited way to do this is to have a dictionary mapping strings to the corresponding FQNs:

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
}

A more complex but powerful way would involve using reflection to search all types from a set of assemblies. Something like this:

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
    }
}

This is not really doable in an efficient fashion in .Net. In order to get a fully qualified name of a type you will need to have the Type object handy. And in order to get a Type object you typically need an instance, the fully qualified name, or you have to do a bit of searching.

The latter works but is not very efficient as you need to search through every assembly and type in the loaded AppDomain to find the correct answer.

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

This solution still won't 100% work for you though. Primarily because there is no type "Int" in the .Net framework. It's actual type name is "Int32".

A type name like "String" can be ambiguous since it could refer to System.String or FooAssembly.String , so you have to search through all types in all loaded assemblies, which could yield multiple results. This bit of reflection could be slow, but you could do the obvious optimization of caching the results at the expense of memory:

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;
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM