We all have those little wonders in our .NET code, those small tips and tricks that make code just that much more concise, maintainable, or performant. Many of you probably already know of some of these, but many folks either overlook them or just don't know about them, so this article is a refresher.

I'm planning on making this a three-part series encompassing 15 little wonders that I had thought of, though I'm very curious to hear the little wonders you can think of as well.

1. The Null Coalescing Operator (??)

This one is such an elegant little operator that can be extremely useful in some situations. How often do you have a variable that you want to use the value of, but if that value is null you want to substitute a default value? For example, say you wanted to assign a string to a variable, but if that string is null you want the empty string instead?

You could, of course, write an if statement:

1:string name = value;

2:

3:if (value == null)

4: {

5: name = string.Empty;

6: }

Or better yet, you could use a ternary operator (?:):

1:string name = (value != null) ? value : string.Empty;

Ah, that's much more concise, but we can get even better! C# adds a null-coalescing operator (??) that is a short-cut for the ternary operator (?:) checking against a null:

1:string name = value ?? string.Empty;

Very nice and concise! You can even write a helper method to trim a string and return null if string is all whitespace so that it can be used with "??".

1:publicstaticclass StringUtility

2: {

3:publicstaticstring TrimToNull(string source)

4: {

5:returnstring.IsNullOrWhiteSpace(source) ? null : source.Trim();

6: }

7: }

Then the null-coalescing operator can be used to turn completely empty strings into defaults.

1:string name = StringUtility.TrimToNull(value) ?? "None Specified";

2. The As Cast

How many times have you seen code like this:

1:if (employee is SalariedEmployee)

2: {

3: var salEmp = (SalariedEmployee)employee;

4:

5: pay = salEmp.WeeklySalary;

6:

7:// ...

8: }

This is redundant because you are checking the type twice. Once in the is check and once in the cast. Whenever you find yourself going down this path, prefer the as cast. This handy cast will cast the type if the types are compatible, or return null if not:

1: var salEmployee = employee as SalariedEmployee;

2:

3:if (salEmployee != null)

4: {

5: pay = salEmployee.WeeklySalary;

6:

7:// ...

8: }

The code reads better without the ugly cast, and you avoid double-checking the type.

3. Auto-Properties

We all know about C# properties, and most of us know about auto properties. They turn code like these two typical properties with backing fields:

1:publicclass Point

2: {

3:privateint _x, _y;

4:

5:publicint X

6: {

7: get { return _x; }

8: set { _x = value; }

9: }

10:

11:publicint Y

12: {

13: get { return _y; }

14: set { _y = value; }

15: }

16: }

Into a much more concise and maintainable piece of code:

1:publicclass Point

2: {

3:publicint X { get; set; }

4:publicint Y { get; set; }

5: }

Much shorter! Whenever you have a simple property that just gets/sets a backing field, you should favor the auto-properties if nothing else for saving a lot of typing! All you need is write the properties with no get/set body and the C# compiler will automatically generate a field for you behind the scenes.

To make things even more fun, you can make auto-properties with asymmetrical access levels! That is, you can make an auto-property "read-only" or "write-only". That is, you can make the get public and the set private or vice versa.

1:publicclass Asymetrical

2: {

3:publicstring ThisIsReadOnly { get; private set; }

4:

5:publicdouble ThisIsWriteOnly { private get; set; }

6: }

This makes it easy to make auto-properties that can be set only by the class itself but read publically and vice-versa (though, in practice write-only properties are rarely useful).

4. The Stopwatch Class

How many times have you wished to log how long a particular piece of code took to execute? Maybe you are trying to track average request time or some such metric, or maybe send a warning message when a stored procedure takes longer than 1 second to execute.

But DateTime is imprecise for this sort of metric. You could also query the high resolution timer using Win32 API calls via PInvoke, but this is also very messy and more error prone.

So what’s a C# developer to do? Enter the Stopwatch class which is in the System.Diagnostics namespace. The Stopwatch class makes it clean and easy to use the high resolution timer through the convenience of a C# class:

Much more precise and very clean. Note there is a static factory method to create a Stopwatch and immediately start it. You also have the option of creating using new and then starting manually as you choose.

TimeSpan factory methods

How many time have you seen a piece of code like this and wondered how long the Sleep was going to before?

1: Thread.Sleep(50);

Now, is that 50 seconds? Milliseconds? It is milliseconds, actually, but what if you ran across something like this in someone’s code:

1:void PerformRemoteWork(int timeout) { ... }

What is this timeout? Seconds? Minutes? Milliseconds? It all depends on the developer! I’ve seen timeouts and intervals in both the BCL and custom code written as either seconds or milliseconds. It’s almost always better to use TimeSpan since it makes it far less ambiguous:

1:void PerformRemoteWork(TimeSpan timeout) { ... }

Now, we don’t need to worry about units because that’s specified when the user constructs the TimeSpan:

1: PerformRemoteWork(new TimeSpan(0, 0, 0, 0, 50));

The disambiguates things from the standpoint of the method itself, but not for the caller! Is the caller passing 50 seconds? Milliseconds? It seems we have a similar issue! This is somewhat confused further by the fact that there are 5 constructs for TimeSpan and they are not all consistent:

Notice how the 3-int constructor is hours minutes seconds, and the 4-int constructor adds days? If you want to specify milliseconds, you need the 5-int constructor. This can be confusing because reading a 4-int constructor may look like hours/seconds/minutes/milliseconds but it’s not.

Enter the TimeSpan static factory methods. These allow you to construct TimeSpans unambiguously:

1: PerformRemoteWork(TimeSpan.FromMilliseconds(50));

Now there’s no ambiguity and it’s perfectly readable! No chance of misconstruing the parameters. There’s also:

1: TimeSpan.FromDays(double days);

2: TimeSpan.FromHours(double hours);

3: TimeSpan.FromMinutes(double minutes);

4: TimeSpan.FromSeconds(double seconds);

So you can easily specify an interval in an unambiguous way. It even works with staticreadonly fields:

1:publicsealedclass MessageProducer

2: {

3:privatestaticreadonly _defaultTimeout = TimeSpan.FromSeconds(30);

4: . . .

5: }

Summary

I hope you enjoyed these five little wonders, I have a stack more to introduce next week. Hopefully you found one you didn’t know about or had forgotten about and can put it to good use!

Feedback

Great post! These kinds of articles are very helpful. I know I somehow missed the null coalescing operator when it was introduced. I eventually saw it used in a code sample and picked it up, but that's one of those tricks that I wish I had known about sooner to use on past projects.

As most of the other commenters have, I've been using the majority of these features already. However, adding even just one to my repertoire as a result of this article is great and means I'm looking forward to the other two installments!

agreed... as you might have noticed from other comments, the features are already known. But the hint here is to realize how they can be used to write cleaner code and getting them into one's habit...

I'd like to add a comment about the as operator: I've seen people use it too many times instead of a plain cast. If there is no type check, and the types are not compatible, a cast is better than using the as operator, since you get an invalid cast exception in the correct place, and not a null reference exception elsewhere. The code of your second wonder is instead the right place for the as operator.

Using NintendoDSTT ds R4i DS console, consumers can enjoy movies, enjoy and conserve pictures, evaluate e-books, hold out tunes and numerous more. amid the good skills of Nintendo ds r4 DSTTis it consume reduced power. It is accessible in industry with quite sensible worth in which consumers can effortlessly choose buy. The product is not just compatible with Nintendo ds and ds lite however it also provide good compatibility with Nintendo dsi. It is essentially a 3rd celebration product which allows its consumers to hold back again up their ds gaming library producing utilization of one cartridge. The Nintendo ds r4 help to custom made developed functions as well.

Using Nintendo ds EZFlashR4i DS console, consumers can enjoy movies, enjoy and conserve pictures, evaluate e-books, hold out tunes and numerous more. amid the good skills of Nintendo ds r4PS3 games is it consume reduced power. It is accessible in industry with quite sensible worth in which consumers can effortlessly choose buy. The product is not just compatible with Nintendo ds and ds lite however it also provide good compatibility with Nintendo dsi. It is essentially a 3rd celebration product which allows its consumers to hold back again up their ds gaming library producing utilization of one cartridge. The Nintendo ds r4 help to custom made developed functions as well.

Unfortunately the ternary is probably the cleanest. You could create a static helper method or extension which would call a delegate to return a field if the item specified were non null and return null otherwise, but that might look muchore awkward than the ternary.

I'd like to add a comment about the as operator: I've seen people use it too many times instead of a plain cast. If there is no type check, and the types are not compatible, a cast is better than using the as operator, since you get an invalid cast exception in the correct place, and not a null reference exception elsewhere. The code of your second wonder is instead the right place for the as operator.

Like anything, it's possible to overuse any "tool" thinking it's the only "tool". I did not mean to infer that you should only ever use the as cast, just that a type check & cast if it's the type you want can be replaced with as.

I like to create a timer class that implements Idisposable and then stop the timer and output in the dispose method. That way you can just wrap the class you would like to time in a using block without having to worry about instantiating a stopwatch object.