2012-06-04 30 views
2

這個問題的上下文是一個MVC應用程序,它接受字符串並希望將它們轉換爲類型並將它們轉換爲通用代碼。如何從typeName字符串轉換爲泛型?

  • 我有一個輸入類型的字符串表示形式。
  • 我似乎無法將Type變量放在<>的一個泛型方法中。
  • 這是否意味着我必須手動拼出所有可能的情況和泛型方法調用?這是做到這一點的正確方法嗎?
  • 如果ModelBinder能夠以某種方式找出類型,我可以爲操作方法public ActionResult Something<T>()設置一個通用類型參數,這將很酷。但我不知道這是否可能。

例如

public ActionResult DoSomething(string typeName, int? id) 
{ 
    var type = Type.GetType(typeName); 
    if (type == typeof(Apple)) DoSomethingElse<Apple>(id); 
    if (type == typeof(Orange)) DoSomethingElse<Orange>(id); 
    //if etc ... to infinity 
} 
+2

反思和泛型不是好朋友。 DozsomethingElse *實際上*需要是通用的嗎?如果它只需要一個Type作爲參數就會容易得多... –

+0

@MarcGravell,我不知道。我的印象是使用泛型會比遍佈各地的類型更加乾燥和多功能。也許這是一個錯誤的印象。我會對個人對泛型的約束性工作感興趣。但如果仿製藥不能提供我想象中的好處,我也會感興趣。 – Benjamin

+0

有興趣看到* – Benjamin

回答

1

如果你只有類型,那麼你會通過反射必須全部。假設「DoSomethingElse」在當前類中的方法:

public ActionResult DoSomething(string typeName, int? id) 
{ 
    Type thisType = this.GetType(); // Get your current class type 
    var type = Type.GetType(typeName); 
    MethodInfo doSomethingElseInfo = thisType.GetMethod("DoSomethingElse"); 
    MethodInfo concreteDoSomethingElse = doSomethingElseInfo.MakeGenericMethod(type); 
    concreteDoSomething.Invoke(this, null); 
} 

這應該爲你工作,但你要注意,它不會是漂亮! ;)

+0

你的意思是這裏的代碼並不漂亮,還是你的意思是會出現其他複雜問題? – Benjamin

+0

@Benjamin對不起,我的意思是你不應該這樣寫。您不應該使用反射爲了使一般工作的東西。你想做的方式不能完成,因爲直到運行時才能知道對象的類型,而編譯時必須知道DoSomethingElse的類型參數。編譯器不可能告訴哪個DoSomethingElse可以解析你的調用,所以這是非法的。如果你使用接口/基類,你可以在對象上調用方法,而不必提前知道它的類型,但泛型不是你的朋友在這個... – Faraday

+0

是否沒有正確的方法從字符串到泛型? – Benjamin

1

既然你不是一個實際調用DoSomething因爲它是一個控制器的方法,沒有辦法的類型分配的方法,如:

public ActionResult DoSomething<T>(int? id) 

因爲它是IIS調用該方法,你沒有任何分配這種類型的方式。現在我不知道有關路由的所有信息,所以也許可以使用路由,但對我來說似乎不太可能。看起來你正在使用枚舉,所以也許你可以使用enum.Parse來實例化或創建一個擴展方法爲int,它可以根據類型來確定它。

+0

他並沒有要求改變「DoSomething」方法。他問他如何在不知道他提前通過泛型方法的類型的情況下使用泛型/反射來調用泛型方法。 – Faraday

+0

其實'int? id'只是一個由實體框架處理的數據庫ID。 – Benjamin

+1

@Vijay:閱讀他最後的一篇子彈聲明。這正是他所要求的。如何通過採用仿製藥避免反思。爲了在這種情況下使用泛型,他必須改變簽名。 –

相關問題