2009-12-16 61 views
0

我不願意做這樣的事情:的typeof或Type.GetType的非限定類型名稱

Type t=typeof(int?); 

Type t=typeof(MemoryStream); 

不過參數是字符串( 「?INT」,」 MemoryStream「等),並且它不在彙編限定類型名稱中,因此Type.GetType(string)將不起作用。

我需要獲取類型的原因是因爲我正在做簡單的代碼生成器應用程序,它需要處理值引用類型不同的方式,並且如果類型是Enumerable它將迭代並執行特定的操作。

你有什麼線索嗎?

回答

1

好了,你可以創建一個編譯器上即時,像這樣:

string getTypeHack = @"using System; public static class TypeHacker {{ public static Type GetThisType() {{ return typeof({0}); }} }}"; 

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp"); 
CompilerParameters parameters = new CompilerParameters(); 
parameters.GenerateInMemory = true; 
parameters.GenerateExecutable = false; 
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, string.Format(getTypeHack, "int")); 

Type hacker = results.CompiledAssembly.GetType("TypeHacker"); 
MethodInfo hack = hacker.GetMethod("GetThisType"); 
Type actualType = (Type)hack.Invoke(null, null); 

...但是這可能是一個非常糟糕的主意。對於您正在測試的每種類型,您都需要一個新的內存中組件。一些問題脫離了我的頭頂:

  • 你將有上面的代碼的內存泄漏城市;你需要減輕這一點。
  • 這會很慢。
  • 這是醜陋的。
  • 您仍然可能有組裝問題,具體取決於您允許的類型。

(我可能真的downvote自己的建議此...):^)

有什麼辦法來重構傳遞一個類型的應用程序?它會讓你的生活變得更加輕鬆。

+0

哇,謝謝!有用!我想我會緩存結果,如果我使用你的解決方案 –

+0

好吧,只是看你的記憶。緩存你所能做的事,儘快處理任何可以隨意使用的東西,併爲像「int」,「string」等低懸的水果創建查找表。如果你想到重構的道路,或者包括Jon這樣的程序集提到,這將全面變得更好。 –

1

原因typeof能夠應付這是編譯器知道內置的C#語法快捷方式(intSystem.Int32X?Nullable<X>等)看看通過使用指令,它知道哪些組件需要查看。

如果您希望能夠處理C#編譯器可以處理的任何事情,那麼您將自己需要這些信息。 (我認爲你不會需要命名空間別名等,但...)

你可以提供它的程序集列表和名稱空間列表來檢查嗎?

+0

我已經做了類似迭代通過AppDomain.CurrentDomain.GetAssemblies()並做大會。GetType但它仍然不起作用 –

0

您可以通過使用 AppDomain.CurrentDomain.GetAssemblies所有類型枚舉()。的SelectMany(A => a.GetExportedTypes())

對於每一類你可以它的名字比較你的名字。

這個效果很好,如果你不使用它太多,因爲性能不是很好。你可以通過創建一個字典來改善它。

+0

Type.Name for int?將Nullable'1所以它會不同於int? 。 所以我不能取決於名稱屬性 –

+0

你是對的 - 泛型類型是一個問題。它只適用於非泛型類型。 – Matthias

相關問題