2012-06-19 31 views
106

如果我收到一個包含類(對象)名稱的字符串,並且希望將此字符串轉換爲實際類型(字符串中的那個),我該怎麼做?將字符串轉換爲C中的類型#

我試圖

Type.GetType("System.Int32") 

例如,它似乎工作。

但是,當我試圖用我自己的對象,它總是返回null ...

我不知道會是怎樣的字符串中提前所以這是我唯一的來源,將其轉換爲它的真正類型。

Type.GetType("NameSpace.MyClasse"); 

有什麼想法?

+1

向我們展示你的樣品不合格代碼,還向我們展示了什麼是原始類型。 –

+0

另外,告訴我們爲什麼/你在做什麼。有可能會有工作將不會要求您發送類型的字符串表示形式。 – Trisped

回答

241

如果類型位於mscorlib或調用程序集中,則只能使用只是類型的名稱(當然,包含其名稱空間)。否則,您還必須包含程序集名稱:

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

如果程序集是強命名的,則必須包含所有這些信息。有關更多信息,請參閱Type.GetType(string)的文檔。

或者,如果你要的程序集的引用已經(例如,通過一個衆所周知的類型),你可以使用Assembly.GetType

Assembly asm = typeof(SomeKnownType).Assembly; 
Type type = asm.GetType(namespaceQualifiedTypeName); 
+4

喬恩,正如你曾經說過的那樣,當你沒有收到優惠券時,因爲你是一位頂級用戶而感到遺憾。真正。當您沒有收到upvotes時也很可惜,因爲最高用戶也回答了這個問題。特別是當你沒有收到upvotes時可惜,因爲Jon Skeet也回答了這個問題:) – abatishchev

+4

@abatishchev我懷疑他只是因爲他是一個頂級用戶而對你投票很多。你的答案稍後一點(因爲他們不會翻過第一個正確的答案,所以更少的人會閱讀它),他的帖子包含更多信息,他的帖子回答了原始問題(請參閱Jon對你的原始帖子的評論)。我考慮過投票喬恩,但因爲他的帖子不容易閱讀。我沒有考慮過對你的投票,因爲你基本上重申了這個問題。簡而言之,不要因爲缺乏贊成票而責怪頂級用戶的存在。 – Trisped

+0

它工作正常......我現在唯一的問題是當我有一個System.Collections.List或IList。我怎樣才能做到這一點 ?因爲我不只想要列表類型,而是列表包含的類型。以列表爲例。請記住,我不知道琴絃中會出現什麼,我只需要投入一個真實的類型。可能嗎 ? – Vinhent

23

嘗試:

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"); 
+6

重點在於Type.GetType爲OP返回null。查看我的答案,找出最可能的原因。 –

+1

它工作正常...我現在唯一的問題是當我有一個System.Collections.List或IList。我怎樣才能做到這一點 ?因爲我不只想要列表類型,而是列表包含的類型。以列表爲例。請記住,我不知道琴絃中會出現什麼,我只需要投入一個真實的類型。可能嗎 ? – Vinhent

+0

可能要指出'inputString'需要是完整的命名空間,因爲這是通過我比較你的他的。 –

9

如果你真的想通過名稱類型,你可以使用以下方法:

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

注意,您可以改善這種大幅度的更多信息,表現你對類型你」重新嘗試加載。

+0

它工作正常...我現在唯一的問題是當我有一個System.Collections.List或IList。我怎樣才能做到這一點 ?因爲我不只想要列表類型,而是列表包含的類型。以列表爲例。請記住,我不知道琴絃中會出現什麼,我只需要投入一個真實的類型。可能嗎 ? – Vinhent

+0

非常好,容易與答案一起工作! +1 – Karamafrooz

3

使用以下方法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(); 
} 
相關問題