Some C# Syntax Tricks

Christmas came a bit early for my team this year when we were told that the company had purchased licenses for both Reflector AND ReSharper!  Naturally I installed both right away.  Of course we’re all familiar with Reflector but haven’t used it lately since it’s no longer free.  ReSharper on the other hand is new to many of us.  I know lots of great developers that swear by it but I’ve never really had a chance to dive in and try it out.  I generally think I’m pretty savvy with C# syntax but after just two days ReSharper has already taught me a few syntax tricks that I’ve adopted.

In my current project I’m trying to isolate some database dependencies in legacy code to allow for better unit testing.  The code I’m working with has some entity-like classes that populate themselves incrementally through various DataSets.  The DataSets are built through traditional ADO.NET and passed into various loading methods to read the data from the appropriate DataRows into the properties.

As part of this refactoring process I’ve extracted some interfaces to represent the various data sources.  Since we don’t have any formal dependency injection in this project I’m using some rudimentary static property injection to supply these. Of course, in order for the old code to continue working, I need to ensure that a default source is provided so I adopted a bit of a pattern that looks something like this:

public interface IDemoDataSource
{
	DataSet GetData(int id);
}

public class PseudoEntity
{
	private static IDemoDataSource _dataSource;

	private class DefaultDataSource : IDemoDataSource
	{
		DataSet IDemoDataSource.GetData(int id)
		{
			// Normally query for a DataSet
			return new DataSet();
		}
	}

	public static IDemoDataSource DataSource
	{
		get
		{
			if(_dataSource == null)
			{
				_dataSource = new DefaultDataSource();
			}

			return _dataSource;
		}
		set
		{
			_dataSource = value;
		}
	}

	private void Load(DataSet ds)
	{
		// Read values from DataSet into Properties
	}

	public void Load(int id)
	{
		var ds = DataSource.GetData(id);
		Load(ds);
	}
}

This is where the first (and I think is more interesting) trick comes in. ReSharper suggested an alternative syntax for the the DataSource property’s getter. The revised property looks like this:

public static IDemoDataSource DataSource
{
	get
	{
		return _dataSource ?? (_dataSource = new DefaultDataSource());
	}
	set
	{
		_dataSource = value;
	}
}

The null-coalescing operator (??) isn’t the interesting part – I’ve used that extensively in the past. What’s interesting is the assignment on the right side of the null-coalescing operator. ReSharper’s suggestion takes advantage of the fact that the assignment operator also returns the value that it assigned. I had no idea it did that despite the documentation stating it pretty clearly. I guess it pays to RTFM!

The next trick is more subtle but still interesting. Continuing with the theme above my new unit tests will provide an alternative IDemoDataSource to the PseudoEntity class. As such, the test implementation will need to return a DataSet that matches what is expected by the class but to avoid the database dependency I’ll have to build it manually. One such implementation would look something like this:

public class FakeDataSource : IDemoDataSource
{
	DataSet IDemoDataSource.GetData(int id)
	{
		var dt = new DataTable();
		dt.Columns.AddRange(
			new DataColumn[]
			{
				new DataColumn("id", typeof(int)),
				new DataColumn("title", typeof(string))
			}
		);

		var ds = new DataSet();
		ds.Tables.Add(dt);

		// Populate table with some data

		ds.AcceptChanges();
		return ds;
	}
}

ReSharper’s suggestion here is subtle but here it is:

public class FakeDataSource : IDemoDataSource
{
	DataSet IDemoDataSource.GetData(int id)
	{
		var dt = new DataTable();
		dt.Columns.AddRange(
			new []
			{
				new DataColumn("id", typeof(int)),
				new DataColumn("title", typeof(string))
			}
		);

		var ds = new DataSet();
		ds.Tables.Add(dt);

		// Populate table with some data

		ds.AcceptChanges();
		return ds;
	}
}

The code is nearly identical to the previous example but there’s one difference and it highlights the power of type inference in .NET. Little did I realize that type inference isn’t limited to var, generics, and lambda expressions – it is also be used with arrays like the one passed to AddRange. Here the compiler understands that we’re building an array by virtue of the square brackets but infers the type from the array elements in the initializer.

The documentation for implicitly typed arrays isn’t quite as obvious as the assignment operator returning a value so I don’t feel as bad not knowing about it.  In fact, the it isn’t even mentioned in the body of the Arrays page!  To learn about implicitly typed arrays you either need to be observant and notice the link to a dedicated page in the Arrays page’s navigation panel or read the C# Version 3.0 Specification.

Seeing that ReSharper has already expanded my C# knowledge I’m even more excited about using it.  I wonder what it will teach me next.

Advertisements

6 comments

  1. Yep – there’re several things like this – I typically suggest reading the language spec first before any coding :-)

    1. I’ll readily admit that I’ve stuck more to “what’s new in ___” type documents and those have served me pretty well. The thing is that although there are changes to the language itself most of the time they’re to support some other, larger framework feature(s) so learning them is a natural side effect of learning those new pieces of the framework (i.e.: nullable types, lambda expressions, and LINQ query syntax). Now, obviously the downfall of relying on these is that a few things like the ones described here will fall through the cracks. On the upside, is that I get a bit of a rush “discovering” these little tidbits :)

    1. Thanks for the idea. I don’t really think that Lazy is appropriate for this scenario. I’m not so concerned about delaying creation of the object as I am with ensuring that I have an instance. By going this route I minimize the change’s footprint and can just call DataSource.GetData() and let the getter resolve the instance if so needed.

      The vast majority of the time the default implementation will be used but it needs to be possible for tests (or possibly some other mechanism) to specify a different one. The main reason I went this route was to ensure that I always have a valid instance and give a convenient way to revert to the default (set the property to null) if needed.

      Another problem with Lazy in this scenario is that T is an interface. From my understanding of the class it really wants a concrete type. I know there’s a constructor overload that accepts Func that I could use to get the correct type but using it would require additional plumbing and make changing the DataSource more complicated.

      Am I missing something?

  2. Things like this keep reminding me to make a Lunch and Learn presentation on Microsoft Moles as an alternative to adding DI for the sake of testing. When I’ve made changes to important assemblies without DI built-in, detouring around methods has helped prove code correctness.

    1. I remember you mentioning Moles before so I just watched a Channel 9 video about it and I think it looks promising. One thing I noticed from the video though is that it’s using a special host under MSTest. Is there anything make it work with NUnit?

      …and yes, I’m too lazy to search for it tonight :)

Comments are closed.