【问题标题】:Why doesn't the Controls collection provide all of the IEnumerable methods?为什么 Controls 集合不提供所有 IEnumerable 方法?
【发布时间】:2010-07-21 18:17:49
【问题描述】:

我不确定 ASP.Net 的 ControlCollection 是如何工作的,所以也许有人可以帮我解释一下。

我最近发现了扩展方法和 Linq 的神奇之处。好吧,我很伤心地发现这不是有效的语法

var c=Controls.Where(x => x.ID=="Some ID").SingleOrDefault();

但是据我所知,Controls 确实实现了提供此类方法的IEnumerable 接口,那么提供了什么?为什么这不起作用?至少我已经为这个问题找到了一个体面的工作:

var list = (IEnumerable<Control>)Controls;
var this_item = list.Where(x => x.ID == "Some ID").SingleOrDefault();

【问题讨论】:

  • 你可以做list.SingleOrDefault(x =&gt; x.ID == "Some ID");

标签: c# asp.net linq extension-methods ienumerable


【解决方案1】:

不,IEnumerable 没有很多扩展方法:IEnumerable&lt;T&gt; 有。它们是两个独立的接口,尽管IEnumerable&lt;T&gt; 扩展了IEnumerable

正常的 LINQ 转换方法是使用 Cast&lt;T&gt;()OfType&lt;T&gt;() 扩展方法,它们扩展了非泛型接口:

IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>();
IEnumerable<Control> controls = Controls.Cast<Control>();

两者之间的区别在于OfType 将跳过任何不属于所需类型的项目; Cast 会抛出异常。

一旦您获得了对泛型 IEnumerable&lt;T&gt; 类型的引用,所有其余的 LINQ 方法都可用。

【讨论】:

    【解决方案2】:

    这只是因为ControlCollection 类出现在泛型之前;所以它实现了IEnumerable,但没有实现IEnumerable&lt;Control&gt;

    幸运的是,IEnumerable 接口上确实存在一个 LINQ 扩展方法,它允许您生成一个 IEnumerable&lt;T&gt; 通过转换:Cast&lt;T&gt;。这意味着你总是可以这样做:

    var c = Controls.Cast<Control>().Where(x => x.ID == "Some ID").SingleOrDefault();
    

    【讨论】:

    • 它没有更新以实现IEnumerable&lt;Control&gt; 是否有原因?这不应该破坏向后兼容性。
    【解决方案3】:

    除了 Jon Skeet 和 Dan Tao 提供的答案之外,您还可以通过显式提供类型来使用查询表达式语法。

    Control myControl = (from Control control in this.Controls
                        where control.ID == "Some ID"
                        select control).SingleOrDefault();
    

    【讨论】:

      【解决方案4】:

      Linq 使用了通用集合。 ControlsCollection 实现 IEnumerable 而不是 IEnumberable&lt;T&gt;

      如果你发现这不起作用

      ((IEnumerable)page.Controls).Where(...
      

      但是,确实如此

      ((IEnumerable<Control>)page.Controls).Where(...
      

      您可以转换为通用 IEnumerable&lt;T&gt; 或访问这样的扩展方法:

       page.Controls.OfType<Control>().Where(c => c.ID == "Some ID").FirstOrDefault();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-08
        • 2012-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-07
        • 2010-10-08
        • 1970-01-01
        相关资源
        最近更新 更多