簡體   English   中英

如何使用類型名稱作為字符串轉換為類型?

[英]How can you cast to a type using the type name as a string?

好吧,我一整天都在思考這個想法,我已經到了我承認我只是完全不知道的部分。 可能我正在做的只是愚蠢的,並且有更好的方法,但這就是我的想法帶給我的地方。

我正在嘗試使用通用方法在 WinForms 中加載表單:

protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
    // Do some stuff
}

表單由 ToolStripMenuItem 加載(通過選擇項目或使用 Open Windows 菜單項)。 它們是延遲加載的,因此 MDI 父級中有表單字段,但在需要它們之前它們為空。 我有一個用於 ToolStripMenuItem_Click 的通用方法,用於處理所有菜單項點擊。 除了 ToolStripMenuItem 的名稱與為它們對應的表單類名稱選擇的模式相匹配之外,該方法沒有真正的方法知道正在調用哪個表單。 因此,使用 ToolStripMenuItem 的名稱,我可以確定所請求的表單類型的名稱以及分配用於存儲該表單的引用的私有字段的名稱。

使用它,我可以使用帶有硬編碼類型和字符串匹配的增長/收縮 switch 語句來調用具有特定類型集(不需要)的方法,或者我可以使用反射來獲取字段並創建類型的實例。 我的問題是, System.Activator.CreateInstance提供了一個無法轉換為我需要的類型的 ObjectHandler。 這是我到目前為止所擁有的片段:

string formName = "_form" + ((ToolStripMenuItem)sender).Name.Replace("ToolStripMenuItem", "");
string formType = formName.Substring(1);

FieldInfo fi = this.GetType().GetField(formName, BindingFlags.NonPublic | BindingFlags.Instance);

FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad = (????)System.Activator.CreateInstance("MyAssemblyName", formType);
}

this.LoadForm(ref formToLoad, false);
fi.SetValue(this, formToLoad);

我知道用於 (??) 的類型的字符串名稱,但在編譯時我不知道類型,因為它發生了變化。 我嘗試了很多方法來讓這個轉換/實例化工作,但沒有一個成功。 我非常想知道是否有可能在只知道字符串類型的情況下執行這樣的轉換。 我嘗試使用Type.GetType(string, string)來執行轉換,但編譯器不喜歡它。 如果有人對如何動態加載表單有不同的想法,因為我只是愚蠢地這樣做,請告訴我。

這個問題通常通過強制轉換為所有潛在類型的公共基類或接口來解決。

在 C# 4 中,您還可以將其分配給一個dynamic變量來保存返回值並在其上調用任意方法。 這些方法將是后期綁定的。 但是,我更願意盡可能堅持使用前一種解決方案。

您最好使用其他采用Type並使用例如Type.GetType(string)重載

FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad =
      (FormWithWorker)System.Activator.CreateInstance(Type.GetType("MyNamespace.MyFormType"));
}

根據您所擁有的, FormWithWorker必須(至少)作為您正在實例化的類型的基類,因此您可以執行以下操作:

FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
    formToLoad = (FormWithWorker)System.Activator.CreateInstance("MyAssemblyName", formType);
}

雖然通用接口是解決此問題的一種方法,但接口並非適用於所有場景。 上面的決定是采用工廠模式(switch 語句 - 具體類選擇)或使用反射。 有一個堆棧帖子可以解決這個問題。 我相信您可以直接將其應用於您的問題:

方法工廠 - 案例與反射

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM