Bindable LINQ vs. continuous LINQ

风格不统一 提交于 2019-11-27 12:07:28

Their are 2 problems both these packages try to solve: Lack of a CollectionChanged event and Dynamic result sets. There is one additional problem bindable solves, additional automatic event triggers.


The First Problem both packages aim to solve is this:

Objects returned by a LINQ query do not provide CollectionChanged events.

Continuous LINQ automatically does this to all queries, with no change:

from item in theSource select item ;

Bindable LINQ does this when you add .asBindable to your query Source Object:

from item in theSource.AsBindable() select item ;

The Second Problem both packages aim to solve is:

Result sets returned from a LINQ Query are static.

Normally when you do a LINQ Query your result set is unchanged until you do a new query. With these two packages, your result set is updated whenever the source is updated. (bad for performance, good for realtime updates)

Example

var theSource = new ContinuousCollection<Customer>();
var theResultSet = from item in theSource where item.Age > 25 select item;
//theResultSet.Count would equal 0.

Because your using Bindable or Continuous LINQ, you could modify theSource, and theResultSet would automatically include the new item.

theSource.Add(new Customer("Bob", "Barker" , 35, Gender.Male)); //Age == 35
//theResultSet.Count would now equal 1.

The Additional Problem Bindable LINQ offers: (Quoting directly from their own page)

contactsListBox.ItemsSource = from c in customers
                              where c.Name.StartsWith(textBox1.Text)
                              select c;

Bindable LINQ will detect that the query relies on the Text property of the TextBox object, textBox1. Since the TextBox is a WPF control, Bindable LINQ knows to subscribe to the TextChanged event on the control.

The end result is that as the user types, the items in the query are re-evaluated and the changes appear on screen. No additional code is needed to handle events.

May I draw your attention to another codeplex project? It's called Obtics and deals with the same issues (http://obtics.codeplex.com).

It addresses both the first the second and the additional problem and takes reactivity to a very deep level (has a demonstration with a LINQ based raytracer).

It claims full support for all LINQ statements an methods of the Enumerable class.

It uses yet another mechanism to create live queries:

var theResultSet = ExpressionObserver.Execute(
    () => from item in theSource where item.Age > 25 select item
).Cascade();

Indeed; the main issue with Continuous LINQ is the inability to use any collection that implements the generic IEnumerable and INotifyCollectionChanged. Bindable LINQ has no problem with using custom collections implementing the two interfaces.

viggity

Another thing to keep in mind, although BindableLinq requires the ".AsBindable()" call in the LINQ statement, CLINQ requires that you use ContinuousCollection<T> instead of ObservableCollection<T>. After looking at both briefly, I think I'm going to go with bindable LINQ.

Nestor

Use bindable LINQ, as it implements IDisposable, and therefore you can control when a query gets disposed. When you dispose it, all the subscriptions to INotifyPropertyChanged will unsubscribe.

Continuous LINQ is supposed to solve this problem with weak events, but it doesn't work as far as I was able to test.

Hmm... this seems to be a problem with bindable LINQ (the second assert fails):

var _source = CreateSource_6People(); //(David, 27), (Mark, 15), (Steve, 30), (Jordan, 43), (Shiva, 30), (Erb, 43)
IBindable<int> bindable = _source.AsBindable().Sum(x => x.Age);
var agesSum = 27+15+30+43+30+43;
Assert.AreEqual(agesSum, bindable.Current); //PASSES

_source[0].Age += 1;
Assert.AreEqual(agesSum + 1, bindable.Current); //FAILS... DISAPPOINTING
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!