Share via


Working with obscure arguments - finale

This post continues what we started with what the problem is and how to avoid it with C# 4, and followed with how not to get into trouble when writing a library.

Let's say that the API is already written. It's from a library that you don't control, or can't change without risking backward compatiblity problems. What do you do then? Honestly, I've never found a fully satisfactory answer - I'd love to hear what readers have to say.

Two of the approaches I've seen and used at one time or another are the following. In the first case, simply add the argument name in comments.

StreamWriter writer = new StreamWriter(@"C:\text.txt", /* append*/ true);

The problem is that you either use line comments, which typically leads you to reformat the call with an argument per line to keep the rest of the call legible, or you use /* and */ like I did in the example, and then it's harder to temporarily comment out code using those markers. It's also not very symmetrical with the rest of the arguments.

The second solution I've used is to declare a local constant, which also helps to propagate changes if I use the same value more than once and I want to keep the usage in sync.

const bool appendTrue = true;
StreamWriter writer = new StreamWriter(@"C:\text.txt", appendTrue);

It's a bit clumsy when you have many constants used in a single method, or if you're repeating the constant in a number of places. I'll tend to include the value in the constant when it's an obvious thing, just to reinfore that it's not a variable - the reader is safe to assume that there's a single value for the identifier, and doesn't need to track where that value come from to understand the code.

Sometimes, you can just to let go, and use a constant in an argument list, and assume your readers will know or look up the value. This is rarely the best decision, but in some cases it might mean "if you're not familiar enough with this value here, you're probably not familiar enough with the API to understand the rest of the code anyway." Kind of a harsh judgement on the reader I think, but it might be warranted in your case.

Finally, I don't mean to pick on boolean values. You'll run into the same problem with passing null as an argument, and a bit more rarely, when passing numeric values. Actually the latter is common for APIs that take numbers as units of time - is it seconds, milliseconds, or what? Ideally a TimeSpan would be used, but ah well.

Enjoy!