1

I have an abstract class as defined here:

public abstract class BaseClientService<T>
    where T : ISubsetInfo
{
    abstract T Extract(Superset superset);
}

This works well for all of my implementation, but now I am faced with an implementation that needs an additional argument in order to perform correctly.

eg

T Extract(Superset superset, int id)    

I'm trying to find the most elegant solution, so am trying to avoid including the second argument as either nullable or optional, but I'm not sure if it is worth the effort...

I also though about wrapping the arguments in an object, and having that object include the id for the edgecase, but I think its making it more complex where I'm trying to make it simpler.

The important constraint for me is that I always have one method to call in the abstract class.

Arkiliknam
  • 1,805
  • 1
  • 19
  • 35
  • 3
    How would you expect the *caller* to know whether or not it had to provide the extra information? – Jon Skeet Jan 04 '12 at 13:47
  • 3
    Could perhaps that implementation have another way of specifying the `id`? constructor injection seems the most obvious. – Marc Gravell Jan 04 '12 at 13:49
  • I'm thinking of now making the abstract class use 2 generic types. One being the subset as it is now. The other being a requirement object. So each implementation knows what requirements are needed to extract a subset through the generic typing. – Arkiliknam Jan 04 '12 at 14:22
  • +1 for just how cool the question sounds. – radarbob Jan 06 '12 at 23:30
  • You can use a closure as a method signature adapter, [as seen here][1] [1]: http://stackoverflow.com/questions/8680146/can-a-method-be-attached-to-a-delegate-with-predefined-parameters/8681954#8681954 – radarbob Jan 06 '12 at 23:42

2 Answers2

0

Extract function does not have to have additional parameters, but then it needs to call some virtual function that will provide additional data if needed, something like Object GetParameter(string parameterName). Derived class must implement this function if its Extract function requires it.

Dialecticus
  • 16,400
  • 7
  • 43
  • 103
0

The solution I went for in the end was to introduce a new generic object to my design called Requirement which would be used to identify additional requirements for the operation:

public abstract class BaseClientService<T, R>
where T : ISubsetInfo
      R : IRequirement
{
    abstract T Extract(R requirement);
}

This solution is much like Dialecticus's proposal, but I prefer this one as my requirement is strongly typed. One could argue the overuse of Generics here, but now that it is in my project, its working like a charm.

Arkiliknam
  • 1,805
  • 1
  • 19
  • 35
  • Was about to post, you will need to use the [Command Pattern](http://en.wikipedia.org/wiki/Command_pattern) as you have if you want the cleanest solution. Otherwise each time something needs a different param you are going to face the same issues. – shenku Feb 24 '12 at 02:58