如何改进我的扩展方法

时间:2011-11-29 04:47:17

标签: c# asp.net

我编写了一个扩展方法,它根据作为函数索引器传递的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的控件。我该如何实现?

5 个答案:

答案 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,即使IDid不相同。如果它们不相同,那么比较它们并假装它们是相同的是什么意思?

我认为你应该使用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而不是子字符串。