it-roy-ru.com

Преобразовать строку в тип C #

Если я получаю строку, содержащую имя класса, и хочу преобразовать эту строку в реальный тип (тот, что в строке), как я могу это сделать?

Я старался

Type.GetType("System.Int32")

например, похоже на работу.

Но когда я пытаюсь с моим собственным объектом, он всегда возвращает нуль ...

Я понятия не имею, что будет в строке заранее, поэтому это мой единственный источник для преобразования его в настоящий тип.

Type.GetType("NameSpace.MyClasse");

Любая идея?

152
Vinhent

Вы можете использовать только имя типа (разумеется, с его пространством имен), если тип находится в mscorlib или в вызывающей сборке. В противном случае вы также должны указать имя сборки:

Type type = Type.GetType("Namespace.MyClass, MyAssembly");

Если Ассамблея строго названа, вы должны также включить всю эту информацию. Смотрите документацию по Type.GetType(string) для получения дополнительной информации.

В качестве альтернативы, если у вас уже есть ссылка на сборку (например, через общеизвестный тип), вы можете использовать Assembly.GetType :

Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);
339
Jon Skeet

Пытаться:

Type type = Type.GetType(inputString); //target type
object o = Activator.CreateInstance(type); // an instance of target type
YourType your = (YourType)o;

Джон Скит прав как обычно :)

pdate: Вы можете указывать сборку, содержащую целевой тип, различными способами, как упоминал Джон, или:

YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClass");
30
abatishchev

Если вы действительно хотите получить тип по имени, вы можете использовать следующее:

System.AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).First(x => x.Name == "theassembly");

Обратите внимание, что вы можете значительно повысить производительность, если получите больше информации о типе, который вы пытаетесь загрузить.

13
Chris Kerekes

используйте следующий метод LoadType, чтобы использовать System.Reflection для загрузки всех зарегистрированных ( GAC ) и ссылочных сборок и проверки для typeName

public Type[] LoadType(string typeName)
{
    return LoadType(typeName, true);
}

public Type[] LoadType(string typeName, bool referenced)
{
    return LoadType(typeName, referenced, true);
}

private Type[] LoadType(string typeName, bool referenced, bool gac)
{
    //check for problematic work
    if (string.IsNullOrEmpty(typeName) || !referenced && !gac)
        return new Type[] { };

    Assembly currentAssembly = Assembly.GetExecutingAssembly();

    List<string> assemblyFullnames = new List<string>();
    List<Type> types = new List<Type>();

    if (referenced)
    {            //Check refrenced assemblies
        foreach (AssemblyName assemblyName in currentAssembly.GetReferencedAssemblies())
        {
            //Load method resolve refrenced loaded Assembly
            Assembly assembly = Assembly.Load(assemblyName.FullName);

            //Check if type is exists in Assembly
            var type = Assembly.GetType(typeName, false, true);

            if (type != null && !assemblyFullnames.Contains(Assembly.FullName))
            {
                types.Add(type);
                assemblyFullnames.Add(Assembly.FullName);
            }
        }
    }

    if (gac)
    {
        //GAC files
        string gacPath = Environment.GetFolderPath(System.Environment.SpecialFolder.Windows) + "\\Assembly";
        var files = GetGlobalAssemblyCacheFiles(gacPath);
        foreach (string file in files)
        {
            try
            {
                //reflection only
                Assembly assembly = Assembly.ReflectionOnlyLoadFrom(file);

                //Check if type is exists in Assembly
                var type = Assembly.GetType(typeName, false, true);

                if (type != null && !assemblyFullnames.Contains(Assembly.FullName))
                {
                    types.Add(type);
                    assemblyFullnames.Add(Assembly.FullName);
                }
            }
            catch
            {
                //your custom handling
            }
        }
    }

    return types.ToArray();
}

public static string[] GetGlobalAssemblyCacheFiles(string path)
{
    List<string> files = new List<string>();

    DirectoryInfo di = new DirectoryInfo(path);

    foreach (FileInfo fi in di.GetFiles("*.dll"))
    {
        files.Add(fi.FullName);
    }

    foreach (DirectoryInfo diChild in di.GetDirectories())
    {
        var files2 = GetGlobalAssemblyCacheFiles(diChild.FullName);
        files.AddRange(files2);
    }

    return files.ToArray();
}
3
Ehsan Mohammadi