Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid or embrace C# constructs which break edit-and-continue?

Tags:

I develop and maintain a large (500k+ LOC) WinForms app written in C# 2.0. It's multi-user and is currently deployed on about 15 machines. The development of the system is ongoing (can be thought of as a perpetual beta), and there's very little done to shield users from potential new bugs that might be introduced in a weekly build.

For this reason, among others, i've found myself becoming very reliant on edit-and-continue in the debugger. It helps not only with bug-hunting and bug-fixing, but in some cases with ongoing development as well. I find it extremely valuable to be able to execute newly-written code from within the context of a running application - there's no need to recompile and add a specific entry point to the new code (having to add dummy menu options, buttons, etc to the app and remembering to remove them before the next production build) - everything can be tried and tested in real-time without stopping the process.

I hold edit-and-continue in such high regard that I actively write code to be fully-compatible with it. For example, I avoid:

  • Anonymous methods and inline delegates (unless completely impossible to rewrite)
  • Generic methods (except in stable, unchanging utility code)
  • Targeting projects at 'Any CPU' (i.e. never executing in 64-bit)
  • Initializing fields at the point of declaration (initialisation is moved to the constructor)
  • Writing enumerator blocks that use yield (except in utility code)

Now, i'm fully aware that the new language features in C# 3 and 4 are largely incompatible with edit-and-continue (lambda expressions, LINQ, etc). This is one of the reasons why i've resisted moving the project up to a newer version of the Framework.

My question is whether it is good practice to avoid using these more advanced constructs in favor of code that is very, very easy to debug? Is there legitimacy in this sort of development, or is it wasteful? Also, importantly, do any of these constructs (lambda expressions, anonymous methods, etc) incur performance/memory overheads that well-written, edit-and-continue-compatible code could avoid? ...or do the inner workings of the C# compiler make such advanced constructs run faster than manually-written, 'expanded' code?

like image 302
Bradley Smith Avatar asked Oct 05 '10 15:10

Bradley Smith


2 Answers

Without wanting to sound trite - it is good practice to write unit/integration tests rather than rely on Edit-Continue.

That way, you expend the effort once, and every other time is 'free'...

Now I'm not suggesting you retrospectively write units for all your code; rather, each time you have to fix a bug, start by writing a test (or more commonly multiple tests) that proves the fix.

As @Dave Swersky mentions in the comments, Mchael Feathers' book, Working Effectively with Legacy Code is a good resource (It's legacy 5 minutes after you wrote it, right?)

So Yes, I think it's a mistake to avoid new C# contructs in favor of allowing for edit and continue; BUT I also think it's a mistake to embrace new constructs just for the sake of it, and especially if they lead to harder to understand code.

like image 113
Mitch Wheat Avatar answered Oct 21 '22 21:10

Mitch Wheat


I love 'Edit and Continue'. I find it is a huge enabler for interactive development/debugging and I too find it quite annoying when it doesn't work.

If 'Edit and Continue' aids your development methodology then by all means make choices to facilitate it, keeping in mind the value of what you are giving up.

One of my pet peeves is that editing anything in a function with lambda expressions breaks 'Edit and Continue'. If I trip over it enough I may write out the lambda expression. I'm on the fence with lambda expressions. I can do some things quicker with them but they don't save me time if I end up writing them out later.

In my case, I avoid using lambda expressions when I don't really need to. If they get in the way I may wrap them in a function so that I can 'Edit and Continue' the code that uses them. If they are gratuitous I may write them out.

Your approach doesn't need to be black and white.

like image 35
Jim Balkwill Avatar answered Oct 21 '22 21:10

Jim Balkwill