【问题标题】:BindingList and LINQ?绑定列表和 LINQ?
【发布时间】:2010-09-24 00:51:32
【问题描述】:

我是 Linq 的新手,我想对 BindingList 中的一些数据进行排序。完成 Linq 查询后,我需要使用 BindingList 集合来绑定我的数据。

 var orderedList = //Here is linq query
 return (BindingList<MyObject>)orderedList;

这个编译成功了,执行失败,这是怎么回事?

【问题讨论】:

    标签: c# .net linq .net-3.5 c#-3.0


    【解决方案1】:
    new BindingList<MyObject>(orderedList.ToList())
    

    【讨论】:

    • 这不会破坏订阅列表中事件的任何人吗?
    【解决方案2】:

    您不能总是将任何集合类型转换为任何其他集合。关于编译器何时检查强制转换,请查看Compile-time vs runtime casting上的这篇文章

    但是,您可以通过自己进行一些管道操作,轻松地从枚举中生成 BindingList。只需将以下扩展方法添加到任何 Enumerable 类型即可将集合转换为 BindingList。

    C#

    static class ExtensionMethods
    {
        public static BindingList<T> ToBindingList<T>(this IEnumerable<T> range)
        {
            return new BindingList<T>(range.ToList());
        }
    }
    
    //use like this:
    var newBindingList = (from i in new[]{1,2,3,4} select i).ToBindingList();
    

    VB

    Module ExtensionMethods
        <Extension()> _
        Public Function ToBindingList(Of T)(ByVal range As IEnumerable(Of T)) As BindingList(Of T)
            Return New BindingList(Of T)(range.ToList())
        End Function
    End Module
    
    'use like this:
    Dim newBindingList = (From i In {1, 2, 3, 4}).ToBindingList()
    

    【讨论】:

    • T 实现INotifyPropertyChanged 时,您可以通过迭代range 并将每个项目直接添加到BindingList 来提高效率。实际上,range.ToList() 将枚举range 以将每个项目添加到List&lt;T&gt;,然后BindingList&lt;T&gt; 将(再次)枚举该列表以将PropertyChanged 事件处理程序连接到每个项目。跳过 .ToList 可以提高非常大的集合的性能。
    【解决方案3】:

    仅当您的 linq 查询的选择投影被显式键入为 MyObject 而不是创建匿名对象实例的 select new 时,上述内容才有效。在这种情况下, typeof(orderedList.ToList()) 的结果类似于: System.Collections.Generic.Listf__AnonymousType1>

    ie:这应该可以工作:

    var result = (from x in MyObjects
                  where (wherePredicate( x ))
                  select new MyObject {
                      Prop1 = x.Prop1,
                      Prop2 = x.Prop2
                  }).ToList();
    return new BindingList<MyObject>( result );
    

    这不会:

    var result = from x in db.MyObjects
                 where(Predicate(x))
                 select new {
                    Prop1 = x.Prop1
                    Prop2 = x.Prop2
                };
    return new BindingList<MyObject>(result.ToList())
    //creates the error: CS0030 "Cannot convert type 'AnonymousType#1' to 'MyObject'
    

    在第二种情况下,它们的 typeof(result) 是:System.Collections.Generic.Listf__AnonymousType2>(类型参数与您选择投影中设置的属性匹配)

    参考:http://blogs.msdn.com/swiss_dpe_team/archive/2008/01/25/using-your-own-defined-type-in-a-linq-query-expression.aspx

    【讨论】:

      猜你喜欢
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2010-10-07
      • 2019-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多