DEV Community

loading...

Discussion on: C# and .NET Core Appreciation Post. The most beautiful piece of code I have ever seen... this month!

Collapse
maartyl profile image
maartyl

I hate C# LINQ query syntax. It is completely pointless. You can always use LINQ methods directly.

This is a warning to anyone who thinks it's cool.

  • It gives you nothing. It's not shorter, it's not more readable, it's not faster... It's actually harder to refactor and maintain.

  • I used to love them at first: they look so cool, right? Well, I've been using C# for many, many years, and the experience has always converged to: avoid them, you will regret the temptation. - Use lambdas directly instead: Lambdas are great.

  • Nice simple example: Often, you need to split the query into 2 places: super simple with normal syntax: you just copy part of it elsewhere, keeping it as IEnumerable/IQueryable. - With LINQ syntax, you now have to figure out how to split the nonlinear query, the beginning and end is always repeated, you have to type them over..... Zero added value, only problems. After all, its design was inspired by the ergonomically ~worst language: SQL. (I admit, this is opinionated; what I say about LINQ syntax: not so much)

  • Most importantly: Not all LINQ/extension methods have LINQ syntax, so now you have to mix it, and it's completely horrible.

  • Also, it has nothing to do with .NET Core: It's been in C# since before 2008.

btw. Don't get me wrong: LINQ extension methods are great... except, for no good reason, C# decided to call all the methods differently than every language ever - but the LINQ syntax was 100% a mistake.

Collapse
maartyl profile image
maartyl

PS: I would love it, if you could prove me wrong. ^^
- I would love to use them... it's just never been worth it.

Collapse
sduduzog profile image
Beautus S Gumede Author

This is going to be hard 😅 You have years of experience, I have a few weeks. Unless they introduce a breaking change that we'll most likely learn at the same pace, there's no way I can defend LINQ as of yet

Thread Thread
maartyl profile image
maartyl

I want to wholeheartedly thank you for this article. I considered LINQ syntax so useless, I forgot about it when trying to figure out how to bend C# to my needs. Thanks to you, I started to wonder what LINQ actually could be useful for, and it has a use!

It can be used to add monadic 'do' syntax sugar. I missed this for a long time, creating all sorts of workarounds. Inventing ways to use the language in manners the language was never meant to be used. (Not stopping now, lol)

Now, I finally found a use for LINQ syntax. I didn't implement it yet, but I am nearly certain it's possible. Implementing the specific SelectMany on my custom type, I should be able to write 'nested' bind calls (thus able to reference previous variables) as a flat sequence of operations.
(I just hope there is not some horrible trap, like there is in mutable async blocks (which makes them useless as generic monad syntax))

var r = from a in m()
        from b in m()
        let aa = a + b
        from c in m()
        select new { aa, b, c };

Imagine m() to be some monadic expression.

If this works, my code will be so much more readable and maintainable thanks to this. ^^ - And if it wasn't for you, I would have never thought about this. So, thank you. ^^

Collapse
sduduzog profile image
Beautus S Gumede Author

I love how this came after I had seen this comment firsthttps://dev.to/fernandomondo/comment/ilae or else I would have been devastated by now. I have rewriten that piece of code in my project using lambda, that whole function is made up of just two lines now. In fact, this is a great neede eye-opener.

Also, it has nothing to do with .NET Core: It's been in C# since before 2008
These guys were in the future already! That's amazing!

Collapse
maartyl profile image
maartyl

I'm glad you saw the other comment first. ^^ I would have hated to make you feel devastated. I just wanted to deter others from repeating my mistakes. ^^ (and clearly, I'm not the only one :D) - I was probably just a bit harsher, because that temptress burnt me many times, before I finally learned. XD

Collapse
brunnerh profile image
brunnerh

The LINQ syntax has some advantages in certain cases. It can be both more readable and shorter if your query is complex (sub-queries/grouping/cross products) or requires temporary state (those tend to not be translatable to SQL and are usually done in memory).

Lambdas add a ton of noise in general because of punctuation (parentheses, braces, arrows) and you have to re-declare the item variable in every chained call.

For a simple query like this using a navigation property and a lambda a simpler, as shown.

It is about knowing when and how to use a tool; most tools are not categorically "useless".

Thread Thread
sduduzog profile image
Beautus S Gumede Author

@maartyl here goes me proving you wrong! 😅

But with this argument, we all come out as winners. The abundance of tools means there's more than one way to do the job.

Thread Thread
maartyl profile image
maartyl

@brunnerh Thank you for a counterexample. I agree that with complex queries they probably become more worthwhile, and at some point almost certainly are nicer than using lambdas directly, however, I would argue a complex query should not even be kept in the code, usually.

(I should note, I'm not too familiar with LINQ to SQL)

  • It can probably be refactored into multiple reusable functions. (and the moment you do this, the LINQ syntax will be worse again) - It probably should be, and using LINQ syntax makes it harder to do so. - At least to me, large queries seem quite hard to read and reason about, whereas 'composing function{s, calls}' is much nicer (I admit, this is probably a matter of opinion, but I often reuse 'subqueries' and that is generally better).

  • (if it is LINQ to objects) I've never seen that complex queries actually needed - Usually, there is no problem using 'lambda' syntax. (although, to be fair: I haven't always tried, but the trying would probably cost more time overall, than just always using one pattern for everything - especially one that INTERRACTS well with everything else in the language)

  • (if it is LINQ to SQL) If it is complex enough: it should probably not be written in C# at all, as LINQ syntax is very limiting, and I've repeatedly found it does not support things I needed, and had to rewrite it in raw SQL anyway.

  • Writing a query that mixes SQL and memory (does not translate to SQL) feels like a code smell to me. I understand there is some benefit to having a purely SQL query, which you then change to actually run in memory, without rewriting it, but it feels more like it would happen by accident, and not behaving as you expect it to. - I like to have a clear separation of what runs where, and generally clear separation between all things that need their own 'governing'.

  • Lambda noise was never much of an issue for me, but I admit this is a good point. I use lambdas everywhere for everything, but someone not as used to them might find it annoying.

Overall, there probably is some use for them (for actual, complex queries) but in my experience, I don't think I've ever encountered it. I guess they may be great for someone else, I just cannot imagine it...

PS: No idea why dev.to notified me the first time, but not again. I've only found this because I came back to report on my own findings.

Collapse
bdwakefield profile image
Benjamin D Wakefield

I am a fan of the fluent API. I never much liked the 'SQL-like' variants. Joins especially were ugly. Getting back an IQueryable and working with that till you need the data is much preferred, IMO.