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?
If the "LittleThing" only has two values, you can return a KeyValuePair<TKey,TValue>
.
If there are more than two, you could always make your own Tuple class, and replace it with .NET 4's when you finally do move to .NET 4.
Otherwise, I would just define the struct with the interface, and include it as part of your API. Namespaces take care of the naming concern...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With