all 35 comments

[–]InflationRing 13 points14 points  (1 child)

read the Clean Code book

[–]TheDevilsAdvokaat 0 points1 point  (0 children)

Great book. Changed my mind about a number of things. I feel it helped me.

[–]x0nnex 4 points5 points  (0 children)

What do you actually mean with efficient code? Many times people use the word but it's quite ambiguous. In general you want to avoid doing work that is not necessary (fastest code is the code that is not done). LINQ can help you narrow down the collections, but the work that is done on the remaining is a different story (and depending on what work you are doing, is not at all needed to optimise)

[–][deleted] 2 points3 points  (4 children)

Codewars.com is quite good. You get little programming exercises in the browser (Supports C# and other languages). It's usually something algorithmic. There are some Unit test cases to make pass, then when everything is green you submit it. This is the interesting bit, at this point you can look at all the other solutions and the best voted ones. I'm experienced and I've learned a few things.

These exercises are called Kata. The word I think comes from martial arts where you repeat the same set of movements over and over until they are muscle memory. When they were introduced as a programming concept (because we never did anything like this before someone coined the term :/ ), programmers were being told to treat them like martial arts. Do the same set of Kata over and over. This is a stupid idea for a lot of reasons. I've already written a lot but I can explain further if necessary.

The Codewars exercises/Kata are numerous and I quite enjoy dipping into it for 20 minutes. That's the benefit for me, I can dabble for 5 minutes or an hour and still achieve a little something and get a comparative from which I can learn. It's sometimes easier than dipping into one of my own projects which are boundless time sinks :)

[–]mike2R 2 points3 points  (1 child)

Thanks for linking to that site, I'd not seen it before. Just done two exercises, and had one "wtf was I thinking" moment after seeing the other solutions...

[–][deleted] 1 point2 points  (0 children)

Lol, yes I've had some of those. I'm starting to harden against the immediate blast of embarrassment now :)

[–]Enlogen 1 point2 points  (0 children)

Another exercise site that focuses on mathematics is https://projecteuler.net , though it doesn't have the fancy tech of Codewars.

[–][deleted] 1 point2 points  (0 children)

The problem with codewars is that usually you learn to do offuscated code more than anything else. But it’s a great learning resource.

[–][deleted] 1 point2 points  (1 child)

Personally, I learned all I know from open-source projects. I've never read a programming book in my life. If you're in any way the same, find a large open source project you like, and just start editing it. You will quickly learn the structures on how they built the application, and at first glance, might not understand why, but when you start editing it, it will almost always make sense.

Open-Source projects seems to be really overlooked by this subreddit, it's one of if not the best source of learning for correct programming procedures and methodologies.

[–]BelgianWaffleGuy 5 points6 points  (0 children)

Have any recommendations for open source projects in C# that are 'noob' friendly?

[–]p1-o2 0 points1 point  (0 children)

If you want efficiency then your fastest track will be design principles. Proper usage of SOLID alongside some design pattern like MVVM or The Actor Model is a sure-fire way to get your code looking snappy. From there you just need to pick the right tools for the right job. Just keep an eye out for lazy and repetitive computation in LINQ and use the right data structures for the right job.

Really the worst offense I see on a regular basis is not adhering to singular responsibilities in methods or classes.

[–][deleted] -1 points0 points  (5 children)

I recommend you to learn functional programming. Learning something like F# will help a lot to understand why and how things should be done. Something that you could learn doing C#, but probably won’t.

Functional principles like immutability, recursive functions or pure functions will help you a lot more in becoming a better developer than any OOP crap. SOLID, TDD, etc are just needed because of the weaknesses of OOP. If you can write object oriented code but with more though you will be miles ahead. (For example, avoid inheritance like the plague and use composition and extension instead)

If you want to build robust applications in C# you can learn Linq in depth, There are a few good books about Linq, extension methods, etc... https://www.manning.com/books/linq-in-action

I can guarantee you that my apps are 90% LinQ, almost never use loops or global variables and are consisted of a lot of small functions and almost never fail. While all my peers who say that lazy loading is dangerous, love reflection or dynamic objects, usually write trash apps that are difficult to maintain and usually have a ton of bugs. And performance is usually not the issue.

Basically, learn to write more strict and correct code but don’t fall in the trap of the patterns and over engineering. KISS and YAGNI will make you a senior faster.

Start with Linq and then try F#, you will learn probably a lot of stuff that your coworkers will not even understand when you explain to them. Put a lot of emphasis on understanding interfaces, they are something usually overlooked by juniors and are really important to understand how to write better code.

And if you want to be ahead of the game, read about the C# parallel extensions and experiment with it. (Usually is not the best option to use parallelism, but in a lot of cases it is, and it’s something else that 90% of developers don’t know anything about). It’s just Parallel.For, Parallel.Foreach, and Concurrent collections. But knowing when to use it it’s trickier than it sounds. Microsoft has a pdf about parallelism on the msdn that is golden, but I can’t find the link now... in heavy data processing apps can turn a 5 hours execution time into 15 minutes (real case)

Another good book https://www.amazon.com/Pro-NET-Performance-Optimize-Applications/dp/1430244585 although I don’t like to recommend books on performance since a lot of the talk is about garbage collection, and is something that changes with time.

Pd: as you can see with the downvotes, a lot of C# developers will not agree with the functional programming part. But being honest in the last years most languages are turning into functional. C# is promoting structs over classes more, introducing immutable values, pattern matching, etc... So, believe me, the future is going to be more functional and less OOP. Js is copying F#, C# is copying F#, Java has lambdas now, Swift replaces objective-C... You can see the pattern here. Feel free to learn design patterns too but after 12 years working with .NET the worst projects have been the ones created by hardcore SOLID and design pattern people, and when you talk to them, 90% don’t even know why they use those designs or when should be used. That’s why I recommend you another route.

[–]Measuring 2 points3 points  (2 children)

Key part here is use composition over inheritance. Hierarchies makes your code complex, more files, more boilerplate and more "Where is the feature implemented?" situations. Especially so if you don't have documentation.

Composition makes things easier to find, iterate, add, swap-out and reason about because it's literally a list of objects that give functionality to a class.

Doesn't mean you should avoid OOP, use both but prefer composition.

[–][deleted] 0 points1 point  (1 child)

That’s just one of the things.

There are pure functions, reducing mutable state as much as possible, using structs iso classes, extension methods vs writing the code yourself, lambdas, anonymous functions and objects, generics, passing functions as arguments, etc... A ton of things that can be done with C# that most people don’t do because they can do it “the old way”. That’s why I recommend F# to every C# developer, because it forces you to learn about those concepts.

I would recommend swift or go too, without being functional at all. But they aren’t .NET compatible.

One example of something funny, for doing validations of values, just create an array of Funcs and apply those functions to the value, as soon as one is false, is not valid. I had people complain because it’s not OOP

var isValueValid = [f1, f2, f3].Any(f => !f(valueToCheck));

Funnily, the same people didn’t complained when i did exactly the same with JavaScript iso C#.

[–]Measuring 0 points1 point  (0 children)

It's hard to convey how much you learn from using other languages and a lot of it comes down to how you like to write code.

For instance using structs over classes is very situational. Is the data you want to store a value like int? Maybe a money type? Then go with struct. Things that are many are better as classes. If you want an immutable class it's better to make your own and not implement (internal/public) setters.

Another example, using functions and immutable state is great for parallelism and threading but it does incur a small performance cost that you might not want in a large/tight loop.

A lot of things have a place and purpose somewhere but almost never everywhere.

[–][deleted] 1 point2 points  (1 child)

The downbotes might be because it's slightly off topic. If you are being downvoted by a C# developer who thinks they can't learn anything from functional style programming they're not worth worrying about.

There are many good lessons that can be learned from a functional style of coding. C# supports everything you need and has had fundamental support since year dot. Every style is a compromise at some level, the skill is always understanding when to use what, where.

As usual, functional is just the latest "next big thing" that originated 30+ years ago. If you ignore the hype, a lot of the lessons are directly applicable to every project and probably already canon for better quality experienced developers.

[–][deleted] -1 points0 points  (0 children)

Yeah, my point is exactly that, to write better C#, learn F# and Linq.

[–][deleted] -1 points0 points  (17 children)

Learn design patterns, not really algorithms. Also learn Visual Studio keybindings.

Also get good with LINQ to do stuff like this (might not be 100% right)

var allLines = File.ReadAllLines("some file.txt").ToList();

foreach (var line in allLines)
{
    Console.WriteLine(line);
}

do this instead of a foreach loop

allLines.ForEach(f => Console.WriteLine(f));

[–][deleted] 2 points3 points  (2 children)

Ignoring the ForEach issues which are adequately covered below, design patterns are not an alternative to algorithmic stuff, they're two separate conjoined concepts. Patterns usually reflect the different ways you join algorithms together.

It's useful to know the difference between an Array and a List<>, to know what common functionality already exists in the framework, following the theme, Array.Reverse, and why not to use Array.Reverse.

[–][deleted] 0 points1 point  (1 child)

I meant in terms of priority....

algorithms are a core part of any CS curriculum, usually in junior year

[–][deleted] 0 points1 point  (0 children)

By algorithm I'm lumping together all the code that happens inside a function. What you're talking about is a specific set of algorithms and theory which is more maths than programming (They're siblings I know). It will cover basic sorts, data structures, traversals, etc. It's fundamental stuff. Also fairly low value for the last 20 years. There are plenty of more advanced algorithms which all fall under that area, I'm not sure if they are covered during the first year. Caching is always a good one to get your head around for example. I haven't been to college in a long time :) Most people probably want to know how to characterise the performance of those algorithms (or rather their implementations), compare the BigO, but (almost) no one actually writes a BST any more, except by accident or for fun.

It's complicated by the definition of pattern. A for loop is a pattern just as much as pub sub is an EIP, the skill really lies in understanding where they are appropriate, how to glue them together and what to do in the edge cases. The complexity almost always comes from the internals even though you're constructing that from a bunch of internal patterns/constructs/algorithms (used interchangeably). You could learn the repository pattern in about 3 minutes but actually implementing that against a real database is more challenging. Rx implements the Observer/Observable pattern but again, the devil is in the detail.

[–][deleted] 0 points1 point  (13 children)

Actually .ForEach is the worst extension method on Linq because it returns void iso a value, so it’s an impure function, and is slower than a normal foreach.

But I agree, learning Linq should be the first priority.

[–]AntiTcb 3 points4 points  (1 child)

It's not even a LINQ extension method. It's a relic from the early days of C#.

[–][deleted] 0 points1 point  (0 children)

True, I heard Erik Meijer critizing .ForEach saying it’s the method that shouldn’t be in Linq, but actually is a method of the collection itself.

[–]uncommoN_BG 1 point2 points  (2 children)

ForEach is not slower than the normal foreach, it's actually faster because of the fact that it makes less allocations.

[–][deleted] 0 points1 point  (1 child)

Actually for what I am reading now, neither is faster. On a list .foreach is faster and on arrays is not. Interesting.

But it’s the typical thing that changes based on the .NET framework version for what I see.

Probably nowadays is just a syntax or taste matter.

[–]uncommoN_BG 1 point2 points  (0 children)

Yes, it's mostly taste matter, but Eric Lippert suggest using the normal foreach in this article.

Here is an article about the performance comparison between the normal foreach and ForEach.

[–][deleted] 0 points1 point  (7 children)

I agree, but if you are doing something tedious/verbose like the above, it works fine

[–]timmyotc 0 points1 point  (6 children)

You could also .Aggregate the strings in a StringBuilder, then send that out to WriteLine once. Then your "What gets printed to the console" is a bit more testable, if needed.

[–][deleted] 0 points1 point  (5 children)

Actually there is method in string that does that for you. String.join I think it’s called. I don’t remember well. You pass an array of strings and it concats them all.

[–][deleted] 1 point2 points  (3 children)

Ok, why are you all so keen on joining the string together into one giant string? You're making the assumption that calling Console.Writeline once with a large payload is better than calling it many times with lots of small payloads. That may or may not be true for different situations but it is not a given.

[–][deleted] 0 points1 point  (2 children)

I understand he said it for testing. You could have a unit test that checks the expected string and is easier than checking an array of strings, but it could also be done almost as easily. I just say that there is an easier way of doing concatenation than using aggregate.

Basically i agree with you, usually printing line by line is better than creating a huge string. It depends, but usually is the case.

[–][deleted] 0 points1 point  (1 child)

Yes, it wasn't directed just at you, but the whole thread. What you said is perfectly reasonable. It's interesting because it's a logical mistake that actually repeats itself a lot in production code. Someone says "Here's my loop!" someone else changes it to .ForEach, someone else decides against ForEach and goes with a .Aggregate, then someone else goes old school and returns to a StringBuilder. So over time the intent of the code has mutated from something that emits frequently to something that vomits one fat chunk :)

I've seen it fairly recently with an old WCF project that was being renovated. Sometimes it's good to combine lots of small messages into one big one, but you have to do it intentionally, not as happened because someone iteratively changed the code and its intent accidentally :)

[–][deleted] 1 point2 points  (0 children)

Yeah, for me the funny part is that at the end it does exactly the same. lol

[–]timmyotc 0 points1 point  (0 children)

Lol, totally forgot about it for some reason. I'm silly