Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation error when overriding a generic type method

I expose the following class in assembly A:

public abstract class ServiceDependencyHost
{
    protected virtual T ReferenceService<T>() where T : ServiceBase
    {
        // Virtual implementation here...
    }
}

I expose this derived class in a separate assembly (B):

public sealed class ProcessServiceOperation : ServiceDependencyHost
{
    public override T ReferenceService<T>()
    {
        // Override implementation here...

        return base.ReferenceService<T>();
    }
}

Using the code as shown above, the compiler complains on this line:

return base.ReferenceService<T>();

The type 'T' cannot be used as type parameter 'T' in the generic type or method A.ReferenceService(). There is no boxing conversion or type parameter conversion from 'T' to 'System.ServiceProcess.ServiceBase'.

Naturally, I tried replicating the constraints in assembly B:

public override T ReferenceService<T>() where T : ServiceBase

But the compiler now warns on the line above...

Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly.

This answer indicates that my solution should have worked. I want to avoid using reflection to expose this method publicly. It should be so simple!

Thanks in advance to anyone who can spot what mistake I am making.

like image 947
AdamStone Avatar asked Jan 12 '14 14:01

AdamStone


People also ask

Can we override generic method in C#?

Similar to John Carpenter's answer, you can override the generic method with the same generic method, but simply use the as operator to check and cast it to the desired type. This has the added benefit of using null-testing to check if the conversion worked.

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.


1 Answers

The issue is not strictly due to generics. The cause of the issue is that the base class method is protected, whilst the derived class method is public.

An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.

Consequently, the compiler assumes that the two methods are distinct, and the derived method fails to inherit the where T : ServiceBase generic constraint from the base method. Since the derived method knows nothing about T, it expectedly complains that T cannot be converted to ServiceBase when you attempt to pass it to the base method.

like image 149
Douglas Avatar answered Sep 23 '22 20:09

Douglas