我编写了一个扩展方法,它根据作为函数索引器传递的Type来查找控件。这是我的扩展方法。
public static T FindControlByType<T>(this Control childCnt, string Id = "")
{
foreach (Control item in childCnt.Controls)
{
if (item is T)
{
if (Id == "")
{
return (T)Convert.ChangeType(item, typeof(T));
}
if (item.ID.Contains(Id))
{
return (T)Convert.ChangeType(item, typeof(T));
}
}
}
//return T
}
我想要返回Type T的控件。我该如何实现?
答案 0 :(得分:2)
如果您添加通用约束以将T
限制为Control
类型,那么您不需要ChangeType
次调用。演员就够了。
public static T FindControlByType<T>(this Control childCnt, string id = "")
where T : Control
{
foreach (Control item in childCnt.Controls)
{
if (item is T && ((id == "" || item.ID.Contains(id)))
{
return (T)item;
}
}
return default(T);
}
答案 1 :(得分:1)
我发现有一件事是没有必要
if (Id == "")
{
return (T)Convert.ChangeType(item, typeof(T));
}
因为Asp.net中的每个控件都必须有id。
为什么不尝试下面的linq类型方法....(这只是建议)
var checkBoxes = this.GetAllControls().OfType<CheckBox>();
答案 2 :(得分:1)
如果您已经验证了它is T
,我不确定为什么要转换该值。
这应该是等价的:
public static T FindControlByType<T>(this Control childCnt, string Id = "")
where T: Control
{
return childCnt.Controls.OfType<T>()
.FirstOrDefault(item => string.IsNullOrEmpty(Id) || item.ID.Contains(Id));
}
答案 3 :(得分:1)
我认为这应该足够了:
public static T FindControlByType<T>(this Control child, string id="") where T: Control
{
return child.Controls.OfType<T>().FirstOrDefault(x => x.ID.Contains(id));
}
顺便问一下,您确定要使用x.ID.Contains(id)
吗?为什么?
如果ID="indians"
和id="indian"
,则ID.Contains(id)
将返回true
,即使ID
和id
不相同。如果它们不相同,那么比较它们并假装它们是相同的是什么意思?
我认为你应该使用x.ID.Equals(id)
:
return child.Controls.OfType<T>().FirstOrDefault(x => x.ID.Equals(id));
答案 4 :(得分:1)
如果此方法真的是按类型查找子Control
,而不是ID
*,那么您可以考虑返回IEnumerable<T>
而不是T
。然后可以使用Linq:
public static IEnumerable<T> FindControlsByType<T>(this Control childCnt, string Id = "")
where T : Control
{
var controls = childCnt.Controls.OfType<T>();
return Id == "" ? controls : controls.Where(c => c.ID.Contains(Id));
}
另外,正如其他人指出的那样,为T
类型参数添加类型约束。
*为此可能FindControl method已经满足您的需求?但请注意,它将搜索精确的ID
而不是子字符串。