David
David

Reputation: 16028

Covariance with generics where type T is a

I need a child class to implement a method that returns a Type T, where T meets certain criteria as follows:

public abstract class NavEntityController<ChildEntity, GenericNavService_T_Entity ...>
  where ChildEntity : NavObservableEntity<GenericNavService_T_Entity>
{
   public abstract T ReadAll<T>(bool forceUpdate = false) where T : NavObservableCollection<ChildEntity>;
   //others
}

I'm trying to implement this as follows in the concrete class:

public class NavJobController : NavEntityController<NavObservableJob, JobCard_Service, JobCard>
    {
       public override NavObservableCollection<NavObservableJob> ReadAll(bool forceUpdate = false)
       {
                //...
       }

}

public class NavObservableJob : ...  {} //Let's just say this is a class or we are going to go down a whole tree of dependencies

But I get the error that my "child class does not implement inherited abstract member ReadAll from the parent".

Upvotes: 0

Views: 94

Answers (1)

Jodrell
Jodrell

Reputation: 35716

A concrete implementation of an abstract class needs to implement the abstract members of the abstract class.

If you have a generic abstract member then you need a generic concrete implementation.

NavObservableJob is more specialized and specific than any NavObservableCollection<ChildEntity> implementation, since NavObservableCollection<T> is not covariant.


To achieve what you want, you need to define NavObservableCollection<T> as an interface. This will allow you to define the interface as covariant, e.g.

public interface INavObservableCollection<out T>
{
   // ...
}

Note: The use of the out Generic Modifier.

Then change NavObservableCollection<T> so that it implements the new interface,

class NavObservableCollection<T> : INavObservableCollection<T>
{
    // ...
}

Then use the interface as your generic constraint,

public abstract class NavEntityController<ChildEntity, GenericNavService_T_Entity>
        where ChildEntity : NavObservableEntity<GenericNavService_T_Entity>
{
    public abstract T ReadAll<T>(bool forceUpdate = false)
            where T : INavObservableCollection<ChildEntity>;

    //others
}

Upvotes: 2

Related Questions