クラスの名前を含む文字列を受け取り、この文字列を実際の型(文字列内の型)に変換したい場合、どうすればよいでしょうか。
私は試した
Type.GetType("System.Int32")
たとえば、うまくいくようです。
しかし、私が自分のオブジェクトを使ってみると、常にnullを返します。
文字列の中に何が含まれるのか私にはわからないので、それを実際の型に変換するための唯一のソースです。
Type.GetType("NameSpace.MyClasse");
何か案が?
型がmscorlib
または呼び出し側のAssemblyにある場合は、(もちろん名前空間を含む)型の名前のみだけを使用できます。それ以外の場合は、アセンブリ名も含める必要があります。
Type type = Type.GetType("Namespace.MyClass, MyAssembly");
議会が厳密に命名されているならば、あなたはその全ての情報も含める必要があります。詳しくは Type.GetType(string)
のドキュメントを参照してください。
あるいは、アセンブリへの参照がすでにある場合(たとえば、よく知られている型を使用して)、 Assembly.GetType
を使用できます。
Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);
試してください:
Type type = Type.GetType(inputString); //target type
object o = Activator.CreateInstance(type); // an instance of target type
YourType your = (YourType)o;
Jon Skeetはいつもどおり正しいです:)
pdate: Jonが述べたように、さまざまな方法でターゲットタイプを含むアセンブリを指定できます。
YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClass");
本当に名前で型を取得したい場合は、次のようにします。
System.AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).First(x => x.Name == "theassembly");
あなたがロードしようとしているタイプに関してあなたが持っているより多くの情報があるほど劇的にこれのパフォーマンスを向上させることができることに注意してください。
次の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();
}