phillip
phillip

Reputation: 2738

Is it possible to define a non-generic interface which can have generic methods?

I was wondering if this code could be improved. The IProvider implements IProvider and overwrites Request(...). I'd like to combine these into a single interface. But I still need a typed and untyped interface to work with.

Is there a way to combine these where I get both or is this how the interfaces should look?

public interface IProvider
{
    DataSourceDescriptor DataSource { get; set; }

    IConfiguration Configuration { get; set; }

    IResult Request(IQuery request);
}

public interface IProvider<T> : IProvider
{
    new IResult<T> Request(IQuery request);
}

Upvotes: 5

Views: 584

Answers (3)

Tengiz
Tengiz

Reputation: 8399

Actually, implementing the interface means you are leaving the base interface's members in child too - inheritance works this way of course.

So, what will happen when you implement your child (generic) interface by some class? Of rouse you will get both generic and non-generic members in the implementor class, which is not exactly what you want as I understand.

Solution:

  1. declare base interface (e.g. IProviderBase) containing "Datasource" and "Configuration" members only.
  2. make IProvider the child of IProviderBase and declare non-generic Request() in it.
  3. make IProvider<T> the child of IProviderBase and declare generic Request<T>() in it.

Makes sense?

Upvotes: 0

VulgarBinary
VulgarBinary

Reputation: 3589

If you want to have the capability to execute untyped code you cannot put that method inside a generic class (and have it still make sense design wise). So the answer is no... what you have is the correct approach when you need untyped and typed interfaces.

However you can have a reference to the initial interface or roll them all into a single interface, but your untyped methods will still have to be declared inside a generic class, ie:

ObjectProvider<SomeObjectType> j = new ObjectProvider<SomeObjectType>();
j.DataSource = //Do something

Now, you could always specify Request as a generic method and allow both to exist in the same context... but... That is in the end up to you.

public interface IProvider
{
    IResult<T> Request<T>(IQuery request);

    DataSourceDescriptor DataSource { get; set; }

    IConfiguration Configuration { get; set; }

    IResult Request(IQuery request);
}

Upvotes: 2

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174309

If the generic type parameter T is only relevant in the context of the Request method, declare only that method as generic:

public interface IProvider
{
    DataSourceDescriptor DataSource { get; set; }

    IConfiguration Configuration { get; set; }

    IResult Request(IQuery request);

    IResult<T> Request<T>(IQuery request);
}

Upvotes: 5

Related Questions