jamietre / CsQuery

CsQuery is a complete CSS selector engine, HTML parser, and jQuery port for C# and .NET 4.
Other
1.15k stars 249 forks source link

Single() #147

Closed fantasticjamieburns closed 10 years ago

fantasticjamieburns commented 10 years ago

Hi,

If I use CQ.First() it returns CQ. If I use the Linq extension method Single(), it returns IDomObject.

Similarly, the following does not compile but feels like it should:

Query.Select( "a:contains('" + text + "')" )
     .Where( a => a.Text() == text );

Generally, it can be confusing composing Linq queries.

Could all/more of Linq's methods be added as extensions to provide the CQ wrapper in a way that is natural for Linq queries?

Jamie.

benjamingr commented 10 years ago

@fantasticjamieburns this is in order to remain compatible with jQuery methods which have this behavior. Methods like .each and event handlers always return a DOM Element and not a jQuery object.

jamietre commented 10 years ago

Right - basically, the jQuery API and LINQ conflict. So unless you explicitly target the LINQ method, e.g.

((IEnumerable<IDomObject>)dom).First()

You'll be using the CsQuery method.

I'm not sure I understand why your other example is conflusing though. CQ objects are collections of IDomObject (or DOM elements). So the Where clause is iterating over IDomObject types, not CQ types. Text is a CQ method, though. So this could be done one of two ways:

// use DOM element property to access text
Query.Select( "a:contains('" + text + "')" )
     .Where( a => a.TextContent == text ); 

or

// convert each element to a CQ object
Query.Select( "a:contains('" + text + "')" )
     .Where( a => a.Cq().Text() == text );