2010-07-15 35 views
4

我試圖做一個通用FindControl方法,我也得到了以下錯誤:不能鍵入「System.Windows.Forms.Control的」轉換爲「T」

無法將類型「System.Windows.Forms的。控制」到 'T'

代碼:

public T Control<T>(String id) 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)ctrl; // Form Controls have unique names, so no more iterations needed 
    } 

    throw new Exception("Control not found!"); 
} 
+0

當你調用這個方法時你爲'T'傳遞了什麼值? – Jamiec 2010-07-15 11:43:17

+0

@Jamiec:那對編譯器來說並不重要,除非你告訴*它總是一個'Control',它不能依賴它,無論你是否總是碰巧一個'Control' ... – 2010-07-15 11:45:44

+0

(離題:)考慮拋出一個更具體類型的異常,可能是'KeyNotFoundException'(來自'System.Collections.Generic'命名空間)。 – stakx 2010-07-15 11:47:56

回答

8

試試這個

public T Control<T>(String id) where T : Control 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)ctrl; // Form Controls have unique names, so no more iterations needed 
    } 

    throw new Exception("Control not found!"); 
} 
+0

當你第一次回答時,你會得到答案! – 2010-07-15 11:45:35

0

你是怎麼稱呼這種方法的,你有沒有例子?

另外,我會約束添加到您的方法:

public T Control<T>(string id) where T : System.Windows.Forms.Control 
{ 
    // 
} 
1

由於T是不受約束的,你可以傳遞的類型參數什麼。你應該在你的方法簽名中添加'where'約束:

 
public T Control<T>(string id) where T : Control 
{ 
    ... 
} 
 
+0

無效的代碼.... – leppie 2010-07-15 11:45:37

+0

您忘了將通用定義添加到方法中:控制(字符串....) – 2010-07-15 11:46:28

+0

糟糕,您確實是對的。糾正。 – 2010-07-19 09:36:52

3

你總是可以彎曲規則並進行雙重轉換。例如:

public T Control<T>(String id) 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)(object)ctrl; 
    } 

    throw new Exception("Control not found!"); 
} 
+1

你可以!但這是一個可怕的想法,考慮到有一個正確的方法來做到這一點 – 2010-07-15 11:47:31

+0

這是處理值類型或基元的唯一方法。但我同意,在這種情況下,「正確」的方式會更好。 – leppie 2010-07-15 11:49:32

-1

你的方法簽名改成這樣:

public T Control<T>(String id) where T : Control 

說,所有T的是Control型的事實。這會限制T,編譯器知道你可以將它作爲T返回。

0

雖然其他人已經正確地指出了問題所在,但我只是想提醒一點,這對於擴展方法來說是非常合適的。不要給予好評這一點,這其實是一個評論,我只是張貼作爲一個答案,這樣我可以獲得寫長和格式化我的代碼更好的能力;)

public static class Extensions 
{ 
    public static T FindControl<T>(this Control parent, string id) where T : Control 
    { 
     return item.FindControl(id) as T; 
    } 
} 

所以,你可以調用它是這樣的:

Label myLabel = MainForm.Controls.FindControl<Label>("myLabelID"); 
相關問題