C#. Is is possible to have a static generic class with a base type constraint that has a method with a further base type constraint

StackOverflow https://stackoverflow.com/questions/3478238

Question

I'd like to be able to create a static generic type with a base type constraint like

public static class Manager<T> where T : HasId
{
    public static T GetSingleById(ref List<T> items, Guid id)
    {
        // the Id is a property provided by HasId
        return (from i in items where i.Id == id select i).SingleOrDefault();
    }
}

Then add another method

...
    public static IEnumerable<T> GetManyByParentId(ref List<T> items, Guid parentId) where T : HasIdAndParentId
    {
        // the parentId is a property of HasIdAndParentId which subclasses HasId
        return from i in items where i.ParentId == parentId select i;
    }
...

Since HasIdAndParentId subclasses HasId the constraint T : HasId is met but the compiler won't accept the where base type constraint on the method.

Any ideas?

Was it helpful?

Solution

In this case, you're not redefining the type parameter on the method, so you can't apply any new constraints. You should be able to do it this way:

public static IEnumerable<T2> GetManyByParentId<T2>(
    ref List<T2> items, Guid parentId) 
    where T2 : T, HasIdAndParentId { .. } 

OTHER TIPS

Make the GetManyByParentId method itself generic, and tie it's generic parameter to T:

public static IEnumerable<R> GetManyByParentId<R>(
                                    ref List<R> items, Guid parentId) 
       where R : T, HasIdAndParentId 

Ben M's code sample will not compile unless HasIdAndParentId is an interface type, which it is not, judjing by the name.

Making the second method itself generic and making it depending on its own type parameter (distinct from T) will provide you the desired constraint.

public static IEnumerable<T1> GetManyByParentId<T1>(ref List<T1> items, Guid parentId) where T1 : HasIdAndParentId
{
    // the parentId is a property of HasIdAndParentId which subclasses HasId
    return from i in items where i.ParentId == parentId select i;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top