Introducing Haystack – a grab bag of extension methods for .NET

Like many developers, I have collected a bunch of useful methods over time. Most of the time, these methods don’t have unit tests, nor do they have performance tests. Many of them have origins at StackOverflow — which uses the MIT license — and many of them don’t.

I started collecting them formally about two years ago. Recently I decided to actually turn them into something I could consume via nuget, because I was getting fed up with copying and pasting code everywhere.

Compatibility

Haystack targets .NET Standard 1.3, which means it works with:

  • .NET 4.6+
  • .NET Core 1.0+
  • Mono 4.6+
  • UWP 10+

Tradeoffs

  • Performance vs maintainability: If I have to choose between maintainability and raw speed, I’ll choose maintainability. To that end, if there were was more than one maintainable approach, I chose the faster of the two, using Benchmark.NET to determine the winner. In some cases, like constant time string comparisons, slower is actually better, so as not to leak information, but only in certain places, so those places where optimizations might leak information are purposely slow, whereas the less security-critical areas use the faster implementation.
  • Correctness: For the most part, each method has unit tests associated with it.

Examples

string.ConstantTimeCompare

Constant time string comparison matter in cryptography for various reasons. To that end, fast string comparisons can leak information, so we want to exhaustively check all the bytes in the string, even if we know the strings aren’t equal early on.

const string here = "Here";
const string there = "There";
 
var areSame = here.ConstantTimeEquals(there);   // false

string.TrimStart and string.TrimEnd

It’s useful to be able to remove substrings from the beginning and/or end of a string. With or without a StringComparer overload.

const string trim = "Hello world";
const string hello = "Hello worldThis is a hello worldHello world";
 
var trimFront = hello.TrimStart(trim);   // This is a hello worldHello world
var trimEnd = hello.TrimEnd(trim);       // Hello worldThis is a hello world
var trimBoth = hello.Trim(trim);         // This is a hello world

The library is growing bit-by-bit, and contributions are welcome!

Leave a Reply

Your email address will not be published. Required fields are marked *