views:

56

answers:

3

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?

+1  A: 

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 
LBushkin
@Ben M: You are correct, I completely misread the question ... I've updated my answer. It seems I need to take a break and get some coffee :)
LBushkin
A: 

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;
}
Gebb
HasIdAndParentId sounds like an (unconventionally-named) interface to me; remember has-a vs. is-a
Ben M
HasId is NOT an interface and doesn't need to be one; Where T: HasId is base type constraint
Scott Rickman
+5  A: 

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 { .. } 
Ben M
Thank you very much Ben
Scott Rickman