It’s a pain that you cannot define constructors for interfaces, isn’t it? To be honest, I’m not so sure… The perceived need for a constructor — typically realized as an Init()-style method — is often a sign of a design…
Nothing beats the real thing
One common pitfall when operating in a mock-heavy TDD context is the tautological test. This is especially true for code which involves awkward dependencies. “I want to avoid talking to the real [database|API endpoint|etc.] here in this class,” you say.…
Living in the test zone
I have previously written that, when given the option of many similar implementation strategies, you should prefer the one which is easiest to test. There is a simple corollary to this proposition: whenever possible, grow your codebase in areas covered…
Take it to the limit: generic type parameters
What is the highest number of generic type parameters can you have on a single type in C#? I know from experience that the answer is at least 130. (Don’t ask.) But is there an upper bound? According to Stack…
Change your Constants
Like Yegor Bugayenko, whenever I see code making heavy use of utility classes, I strongly suggest alternatives that better fit the domain. I have also noticed that where Utility classes are found, their evil cousins — Constants classes — tend…
Async minutiae: EndOfStream
Consider the following method to read all text of a file asynchronously. Do you see any issues? The code is perfectly functional and produces the correct result. There are no obvious performance issues (other than perhaps some tuning of the…
Binary implosion: use the source!
As I’ve written previously, we seem to have a real problem with binary explosion and we would do well with some techniques to curtail it (such as a monolithic core design). Today I want to talk about another definitely-not-new practice…
Fill in the blanks: an async exercise
A Task-based async operation can either complete synchronously (i.e. return a completed Task right away) or asynchronously (the more common case). Given two sequentially awaited operations, there can thus be four possible behavior combinations: Task 1 Task 2 sync sync…
Binary implosion via the monolithic core
Long ago, I wrote about binary explosion — the practice of building a large number of assemblies to provide comparatively little functionality. Despite my protestations, I do not see this problem lessening any time soon. If anything, with the increasing…
Async recipes: after first (matching) task, cancel rest
When it comes to the Task-based Asynchronous Pattern, there are easy patterns to run tasks sequentially (await in a loop) and all in parallel (add to list, await WhenAll). Things get slightly more complicated when the execution model doesn’t fit…