Pass Generic Type up the Inheritance Tree

Question

I have the following classes:

abstract class Foo<T>
abstract class BaseClass : Foo<BaseClass>
class DerivedOne : BaseClass
class DerivedTwo : BaseClass

Using this structure, all class that derive from BaseClass inherit from Foo<BaseClass>. I want to be able to set the generic type of T different in each derived class

For example, in DerivedOne I want the class to be Foo<DerivedOne> but in DerivedTwo I want the class to derive from Foo<DerivedTwo>.

Is there any way to pass the generic type up the inheritance tree?

I tried doing something like this (which doesn't work).

abstract class Foo<T>
abstract class BaseClass<T> : Foo<T>
class DerivedOne : BaseClass<DerivedOne>
class DerivedTwo : BaseClass<DerivedTwo>

Edit: changed generic types to show that they are passing in themselves as generic types

Edit #2: Here is a code sample of the actual classes I am using:

public abstract class DBObject<T> 
    where T : DBObject<T>, new()
{ 
    //the generic type is for this method, so I can create an object from a database query
    public static T Create(DataRow dataRow)
    {
        Type T = MethodBase.GetCurrentMethod().DeclaringType;
        T obj = new T();

        foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (dataRow.Table.Columns.Contains(field.Name))
            {
                Object safeObj = Convert.ChangeType(dataRow[field.Name].ToString(), field.FieldType);
                field.SetValue(obj, safeObj);
            }

        }

        foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            Console.WriteLine(field.Name + "=" + field.GetValue(obj));
            //propInfo.SetValue(obj, value, null);
        }
        return obj;            
    }
}

public abstract class Contact<T> : DBObject<T> 
    where T : Contact<T>
{ 
    //field and methods ommitted...
}

public class Person : Contact<Person>
{ 
    //fields and methods ommitted...
}

public class Company : Contact<Company>
{
    //fields and methods ommitted...
}

The classes can then be used in such a manner:

Person person = Person.Create(/* DataRow from a query result */);

Show source
| generics   | c#   | inheritance   2017-01-05 04:01 1 Answers

Answers ( 1 )

  1. 2017-01-05 05:01

    I get your code to compile if you add the new() constraint to Contact<T>:

    public abstract class Contact<T> : DBObject<T> 
        where T : Contact<T>, new()
    { 
        //field and methods ommitted...
    } 
    

    This is necessary since generic constraints aren't inherited.

◀ Go back