【问题标题】:Get the child controls with type T of a control获取控件类型为 T 的子控件
【发布时间】:2012-11-26 15:25:44
【问题描述】:

我有以下函数来获取所有类型的子控件。

    private IEnumerable<Control> GetControlsOfType(Control control, Type type)
    {
        var controls = control.Controls.Cast<Control>();

        return controls.SelectMany(ctrl => GetControlsOfType(ctrl, type))
                                  .Concat(controls)
                                  .Where(c => c.GetType() == type);
    }

我正在尝试使用泛型类型参数对其进行转换。

    private IEnumerable<T> GetControlsOfType<T>(Control control) where T: Control
    {
        var controls = control.Controls.Cast<Control>();

        return controls.SelectMany(ctrl => GetControlsOfType<T>(ctrl))
                                  .Concat(controls)
                                  .Where(c => c.GetType() == T);
    }

代码在.Concat上有错误。

错误 6 'System.Collections.Generic.IEnumerable&lt;T>' 不包含 'Concat' 的定义和最佳扩展方法重载 'System.Linq.Queryable.Concat&lt;TSource>(System.Linq.IQueryable&lt;TSource>, System.Collections.Generic.IEnumerable&lt;TSource>)' 有一些无效 论据

如何解决这个问题?

【问题讨论】:

    标签: c#


    【解决方案1】:

    尝试在GetControlsOfType&lt;T&gt;(ctrl) 之后添加.OfType&lt;Control&gt;(),而不是您的Where

    所以你的代码如下:

    return controls.SelectMany(ctrl => GetControlsOfType<T>(ctrl).OfType<Control>())
                                      .Concat(controls)
                                      .OfType<T>();
    

    【讨论】:

    • 他想返回IEnumerable&lt;T&gt;——这不是返回IEnumerable&lt;Control&gt;吗?
    • GetControlsOfType&lt;T&gt;(ctrl) 已经具有IEnumerable&lt;Control&gt; 的类型。为什么这里需要OfType&lt;Control&gt;()
    • @NickW 因为'System.Collections.Generic.IEnumerable&lt;T&gt;' does not contain a definition for 'Concat',但是IEnumerable&lt;Control&gt; 可以。您经常会发现 Collections 存在相同的问题,但使用相同的解决方法:)
    • @dav_i 很有趣,很好奇微软为什么不为IEnumerable&lt;T&gt; 创建Concat
    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 2018-01-31
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    相关资源
    最近更新 更多