【问题标题】:Generic All Controls Method通用所有控制方法
【发布时间】:2013-07-03 17:21:08
【问题描述】:

想不出更好的标题,所以很抱歉..

我正在尝试将this method(它将检索表单的所有子控件)转换为扩展方法并接受接口作为输入。到目前为止,我最多

public IEnumerable<Control> GetAll<T>(this Control control) where T : class
{
    var controls = control.Controls.Cast<Control>();

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

除了我需要在调用它以访问其属性时添加OfType&lt;T&gt;() 之外,它工作正常。

例如(这个 == 形式)

this.GetAll<IMyInterface>().OfType<IMyInterface>()

我正在努力将返回类型变成通用返回类型IEnumerable&lt;T&gt;,这样我就不必包含OfType,它只会返回相同的结果但可以正确转换。

大家有什么建议吗?

(将返回类型更改为IEnumerable&lt;T&gt; 会导致Concat 抛出

实例参数:无法从 'System.Collections.Generic.IEnumerable&lt;T&gt;' 转换为 'System.Linq.ParallelQuery&lt;System.Windows.Forms.Control&gt;'

【问题讨论】:

  • 用“public IEnumerable”替换“public IEnumerable”?
  • 导致底部的错误被抛出

标签: c# winforms linq generics


【解决方案1】:

问题是Concat 也需要IEnumerable&lt;T&gt; - 而不是IEnumerable&lt;Control&gt;。不过这应该可行:

public static IEnumerable<T> GetAll<T>(this Control control) where T : class
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAll<T>(ctrl))
                                .Concat(controls.OfType<T>()));
}

【讨论】:

  • @Servy:我不这么认为——controls 在我们递归时仍然是所有子控件。 OfType 仅适用于 direct 子级。
  • 是的,在这种情况下,它首先递归,所以没问题,大多数实现都没有。
  • @JonSkeet - 感谢您的回复,这导致与我的问题中的最后一句相同的问题(Concat 无法从 Control 转换为 T)
  • 我只会添加 'where T : Control' 而不是 'where T : class',因为无论如何该方法仅适用于 Control 派生类。
  • 没关系,当我重建时,错误似乎自行消除了,谢谢!。 @RogerN,我的接口不是来自控制
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 2020-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多