2010-07-15 71 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"); 
相关问题