Another C# Idea: Interface Method Chaining
Let's say I have an interface with method overloads like this:
interface IFoo
{
IList<Order> GetOrdersByDate(DateTime orderDate);
IList<Order> GetOrdersByDateRange(DateTime fromDate, DateTime toDate);
}
It has two methods to get orders by date - one that gets orders for a single day, and another that gets them for a range of dates. Pretty straight forward.
Let's also assume that you want the logic for getting orders for a single date to be the same as getting them for a range of dates. When implementing the interface, you know that 99% of the time you're just going to call one method from the other, like this:
public IList<Order> GetOrdersByDate(DateTime orderDate)
{
return GetOrdersByDateRange(orderDate, orderDate);
}
I think it would be handy to be able to enforce this behaviour back in the interface, in such a way that the implementing class didn't even have to implement the method if they chose not to. You could define your interface like this:
interface IFoo
{
IList<Order> GetOrdersByDateRange(DateTime fromDate, DateTime toDate);
IList<Order> GetOrdersByDate(DateTime orderDate)
: GetOrdersByDateRange(orderDate, orderDate);
}
So now our interface is defining a default "chaining" behaviour for the single-parameter method. If you want to, you can implement that method in your class, but if you don't, it'll just call your implementation for the first method.
So it's sort of like being able to specify default values for parameters back at the interface definition. I think the constructor-chaining-style syntax is nice and understandable. What do you think?
Update: I just realised that you could achieve something very similar using an extension method on an interface to define one of the methods. That's so crazy it might work!
# Trackback from Jason Haley on 29/05/2008 12:14 AM
# Trackback from Reflective Perspective - Chris Alcock » The Morning Brew #103 on 29/05/2008 5:10 PM
# Trackback from Weekly Link Post 44 « Rhonda Tipton’s WebLog on 2/06/2008 6:14 AM
Comments
# Richard
29/05/2008 1:23 AM
That sounds just like Traits in Scala.
# mabster
29/05/2008 8:31 AM
@Richard I'll check 'em out. I've never done any Scala.
# Greg M
29/05/2008 1:39 PM
And Haskell type classes do this too.
# sean
4/07/2008 7:21 PM
perhaps you can help, it is similar to your post:
99% of the time I say "err what?", but sometimes I might say other stuff. In code that translates as
public void SayStuff() : SayStuff("err what?") {}
public void SayStuff(string sayWhat){
Console.WriteLine("You say {0}", sayWhat);}
but this isn't right and doesn't compile, although I'm sure I have done this before. you done this?
# mabster
4/07/2008 7:25 PM
In simple classes, Sean, this is pretty simple:
public void SayStuff()
{
SayStuff("err what?");
}
public void SayStuff(string s)
{
Console.WriteLine("You say {0}", s);
}
So rather than the cool ":" chaining syntax (which only works for constructors) you simply call one method from the other.
# sean
4/07/2008 8:38 PM
that's cool - I thought that I'd seen the : chaining on a method in c# just like a constructor calling :this(..) or :base(..) but maybe not. It wouldn't add too much anyway as the example you've given is concise and readable. many thanks.