You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何快速获取非System命名空间下的指定字符串名称类型?

Efficient Type Resolution from Full Names (No Hardcoding)

Great question! I’ve dealt with this exact problem before—Type.GetType() only checks mscorlib and the current assembly by default, so it misses types from assemblies like System.Drawing.dll. And iterating through all 22 loaded assemblies on every call is a huge waste when you need to do this 10,000 times. Here’s an optimized solution that prioritizes speed and avoids hardcoding:

Core Strategy: Cache + Targeted Assembly Lookup

The key is to minimize assembly scanning by:

  1. Caching resolved types so we never look up the same type twice
  2. Mapping common namespaces to their assemblies to skip full assembly scans for known types
  3. Using a fallback scan only when absolutely necessary

Implementation Code

using System;
using System.Collections.Generic;
using System.Reflection;

public static class TypeResolver
{
    // Cache for already-resolved types (O(1) lookup after first hit)
    private static readonly Dictionary<string, Type> _resolvedTypes = 
        new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);

    // Predefined mapping of common namespaces to their assembly names
    // Add more entries based on your application's used assemblies
    private static readonly Dictionary<string, string> _namespaceToAssembly = 
        new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
    {
        { "System.Drawing", "System.Drawing" },
        { "System.Windows.Forms", "System.Windows.Forms" },
        { "System.Xml", "System.Xml" },
        // Add other namespaces you frequently use here
    };

    /// <summary>
    /// Resolves a type from its full name (e.g., "System.Drawing.Color") efficiently
    /// </summary>
    public static Type ResolveType(string fullTypeName)
    {
        // First check the cache—return immediately if we've seen this type before
        if (_resolvedTypes.TryGetValue(fullTypeName, out Type resolvedType))
        {
            return resolvedType;
        }

        // Try to find the assembly via namespace mapping first
        string namespacePrefix = ExtractNamespace(fullTypeName);
        if (!string.IsNullOrEmpty(namespacePrefix) && 
            _namespaceToAssembly.TryGetValue(namespacePrefix, out string assemblyName))
        {
            try
            {
                Assembly targetAssembly = Assembly.Load(assemblyName);
                resolvedType = targetAssembly.GetType(fullTypeName, throwOnError: false, ignoreCase: true);
                if (resolvedType != null)
                {
                    _resolvedTypes[fullTypeName] = resolvedType;
                    return resolvedType;
                }
            }
            catch (FileNotFoundException)
            {
                // Assembly not found—fall through to full scan
            }
        }

        // Fallback: Scan all loaded assemblies (only runs once per unknown type)
        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            resolvedType = assembly.GetType(fullTypeName, throwOnError: false, ignoreCase: true);
            if (resolvedType != null)
            {
                _resolvedTypes[fullTypeName] = resolvedType;
                return resolvedType;
            }
        }

        // Type not found anywhere
        return null;
    }

    private static string ExtractNamespace(string fullTypeName)
    {
        int lastDotIndex = fullTypeName.LastIndexOf('.');
        return lastDotIndex > 0 ? fullTypeName.Substring(0, lastDotIndex) : null;
    }
}

How This Works

  1. Cache First: Every time we resolve a type, we store it in _resolvedTypes. For 10k calls, after the first lookup for a given type, all subsequent calls are instant.
  2. Namespace Mapping: For common namespaces you use (like System.Drawing), we jump straight to the correct assembly instead of scanning all 22. This cuts down initial lookup time drastically.
  3. Fallback Scan: If the type isn’t in the cache or mapped namespace, we fall back to scanning all assemblies—but only once per unique type.

Optional Optimization: Preload Assemblies

If you know exactly which assemblies you’ll need types from, you can preload all their types into the cache at startup to eliminate even the initial scan:

// Call this once at app startup
public static void PreloadAssemblyTypes(string assemblyName)
{
    Assembly assembly = Assembly.Load(assemblyName);
    foreach (Type type in assembly.GetTypes())
    {
        if (!_resolvedTypes.ContainsKey(type.FullName))
        {
            _resolvedTypes[type.FullName] = type;
        }
    }
}

// Example usage:
TypeResolver.PreloadAssemblyTypes("System.Drawing");

This way, even the first call for System.Drawing.Color is a cache hit.

内容的提问来源于stack exchange,提问作者YogoWafel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:06:49