ForWiz
ForWiz

Reputation: 145

Generic Parameters multiple where-clause issue

I apologize for a weak title, but I have no idea on how exactly to phrase my problem in 1 sentence.

In order to explain my issue, I'm first going to paste my code for better understanding. I have a class Generic:

    public class Generic<TObject, ID>
        where TObject : class, Entity<ID>
        where ID : IComparable

Now I want to use objects of this class, and its children, as parameters for another class. Something like this:

    public class GenericService<TGeneric> 
         where TGeneric: Generic<TObject, ID>
         where TObject: class, Entity<ID>
         where ID : IComparable

But the above code gives me an error in the last 2 where clauses. Error message says something along the lines of Cannot resolve symbol TObject/ID, because I have not put them in the initial generic parameter brackets.

I did a refactor, where TObject and ID were passed as generic parameters, like this:

    public class GenericService<TGeneric, TObject, ID> 
         where TGeneric: Generic<TObject, ID>
         where TObject: class, Entity<ID>
         where ID : IComparable

and it works. But I want to avoid writing 3 generic parameters if possible, since those parameters are drawn from the TGeneric parameter.

I am attempting this approach because of the following scenario. If I had a class ChildGeneric:

public class ChildGeneric : Generic<SomeEntity, SomeID>

and I want to pass it to GenericService, I want to be able to write only

GenericService<ChildGeneric> service = new GenericService<ChildGeneric>

instead of

GenericService<ChildGeneric, SomeObject, SomeID> = new GenericService<ChildGeneric, SomeObject, SomeID>

Is there a way to refactor the 2nd code snippet in order to make it work with the TGeneric parameter only?

Upvotes: 0

Views: 469

Answers (1)

Jakub Fojtik
Jakub Fojtik

Reputation: 706

If your GenericService class does not care about the generic arguments of the nested class you can use a non-generic interface:

public interface IGeneric
{
    //API for everything you do care for in other classes
    //must not use the TObject, ID types
}

just like IEnumerable<T> implements IEnumerable. Although that may just be for historical reasons.

The downside is having to keep the interface in sync with the class.

If your GenericService does care for the TObject, ID types, then you need to define them on the class like you did, or specify them in an implementing class as Camilo wrote in the comments.

Upvotes: 1

Related Questions