I’m writing a method in C# (2.0) that has to return a collection of simple objects. Normally I would do something like this:
class MyWidget
{
struct LittleThing
{
int foo;
DateTime bar;
}
public IList<LittleThing> LookupThings()
{
// etc.
}
}
However, I have to declare this method in an interface. The caller doesn’t get to see MyWidget, only an IWidget interface. The above setup doesn’t work in that situation, because C# does not allow defining types inside an interface. What is the proper or best way to do such a declaration?
The straighforward thing I thought of is to simply declare LittleThing outside of the interface. That doesn’t seem great, for a couple of reasons. One: it is only ever used by that single method in that single class, so it doesn’t seem that LittleThing should be an independent type just floating around by itself. Two: if similar methods wind up being written for other classes, they will be returning different kinds of data (for good design reasons), and I don’t want to clutter the namepace with a ton of similar-named structs that differ only slightly from each other.
If we could upgrade our version of .Net, I would just return a Tuple<>, but that’s not going to be an option for some time yet.
[Edited to add: The small object does need to contain more than two fields, so KeyValuePair<K,V> won’t quite cut it.]
[Edited to add further: IWidget is implemented by only one class, Widget. I think it weird to have an interface for only one class, but this was done to satisfy an old coding policy that required the contract to always be in a separate assembly from the implementation. Said policy has now gone away, but we haven’t the resources to refactor the entire application and remove all the unnecessary interfaces.]
What’s the best practice?
Why wait? It’s not like a tuple is a complicated thing. Here’s the code for a 3-tuple.
As you can see, it’s no big deal. What I’ve done on my current project is implement 2, 3 and 4-tuples, along with a static
Tupleclass withCreatemethods on it, which exactly mirror the .NET 4 tuple types. If you’re really paranoid you can use reflector to look at the dissassembled source code for the .NET 4 tuple, and copy it verbatimWhen we eventually upgrade to .NET 4, we’ll just delete the classes, or
#ifdefthem out