(Miss)Use of Narrowing-Implicit Operators

17 Mar 2011

I have covered a use of Narrowing/Implicit Operators before, but I was thinking the other day about use of Fluent Interfaces, and if it was possible to have one on a cache/repository type class, that would allow you to chain options together, but stop at any point and have the result.

I gave it a go, and came up with this:

public class Person
{
	public string Name { get; set; }
	public int Age { get; set; }

	public Person(string name, int age)
	{
		this.Name = name;
		this.Age = age;
	}
}

public class PersonManager
{
	public static PersonOptions GetPerson()
	{
		return new PersonOptions(new Person("dave", 21));
	}
}

public class PersonOptions
{
	public Person Person { get; private set; }

	public PersonOptions(Person person)
	{
		this.Person = person;
	}

	public PersonOptions WaitForFreshResults()
	{
		//...
		return this;
	}

	public static implicit operator Person(PersonOptions options)
	{
		return options.Person;
	}
}

Which can be used like so:

Person p1 = PersonManager.GetPerson();
Person p2 = PersonManager.GetPerson().WaitForFreshResults();

Which is all very well and good - but nowadays, everyone (well nearly everyone) loves the var keyword, so what happens if it is used like this:

var p3 = PersonManager.GetPerson();
var p4 = PersonManager.GetPerson().WaitForFreshResults();

Uh oh. That’s not a person you have in that variable, it’s a PersonOptions. The compiler does help with this, as none of your Person methods will be present, and the PersonOptions class does provide a Person object as a Read Only Property, so the code can be modified to use that:

var p5 = PersonManager.GetPerson().WaitForFreshResults().Person;

I’m not entirely comfortable with using implicit conversions like this, especially with var, but it does work rather well, as long as you are careful.

design, c#

« Expression Rules, Version 2 Differences between Properties and Auto Properties »