212

クラスの名前を含む文字列を受け取り、この文字列を実際の型 (文字列内の型) に変換したい場合、どうすればよいですか?

私は試した

Type.GetType("System.Int32")

たとえば、機能しているように見えます。

しかし、自分のオブジェクトで試してみると、常に null が返されます...

文字列に何が入るか事前にわからないので、実際の型に変換するための唯一の情報源です。

Type.GetType("NameSpace.MyClasse");

何か案が?

4

4 に答える 4

437

型が inまたは呼び出し元のアセンブリにある場合は、型の名前のみ (もちろん、その名前空間を含む)のみを使用できますmscorlibそれ以外の場合は、アセンブリ名も含める必要があります。

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

アセンブリに厳密な名前が付けられている場合は、そのすべての情報も含める必要があります。詳細については、ドキュメントを参照してType.GetType(string)ください。

または、アセンブリへの参照が既にある場合 (たとえば、よく知られている型を介して)、次を使用できますAssembly.GetType

Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);
于 2012-06-19T18:57:40.303 に答える
38

試す:

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

ジョンスキートはいつものように正しいです:)

更新: Jonが述べたように、さまざまな方法でターゲットタイプを含むアセンブリを指定できます。または:

YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClass");
于 2012-06-19T18:58:59.447 に答える
19

本当に名前でタイプを取得したい場合は、次を使用できます。

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

ロードしようとしているタイプに関する情報が多いほど、このパフォーマンスを大幅に改善できることに注意してください。

于 2012-06-19T19:07:40.297 に答える
4

次の 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();
}
于 2013-01-04T21:43:33.167 に答える