1

Is it possible to override generics constraints for abstract methods implementation?

Let me explain... normally I would do something like:

public abstract class A
{
    public abstract class IData {}

    public abstract void DoSomething(IData data);
}

public class B : A
{
    public DataB : IData
    {
        public int ciao;
    }

    public override void DoSomething(IData data)
    {
        DataB d = data as DataB;

        if (d == null)
        {
             // print error or whatever...
             return;
        }

        int miao = d.ciao * 2;
        // do whatever with miao or d.ciao...
    }
}

public class C : A
{
    public DataC : IData
    {
        public float arrivederci;
    }

    public override void DoSomething(IData data)
    {
        DataC d = data as DataC;

        if (d == null)
        {
             // print error or whatever...
             return;
        }

        int bau = d.arrivederci * 2f;
        // do whatever with bau or d.arrivederci...
    }
}

What I don't like is that I can pass to the DoSomething function an invalid parameter type.

I would want to be able to do something like

public class B : A
{
    public DataB : IData
    {
        public int ciao;
    }

    public override void DoSomething(DataB data)
    {
        int miao = d.ciao * 2;
        // do whatever with miao or d.ciao...
    }
}

public class C : A
{
    public DataC : IData
    {
        public float arrivederci;
    }

    public override void DoSomething(DataC data)
    {
        int bau = d.arrivederci * 2f;
        // do whatever with bau or d.arrivederci...
    }
}

which of course is not possible.

For this reason I ended up doing something like:

public abstract class A
{
    public abstract class IData {}

    public abstract void DoSomething<T>(T data) where T : IData;
}

The next step would be to make something like

public class B : A
{
    public DataB : IData
    {
        public int ciao;
    }

    public override void DoSomething<T>(T data) where T : DataB
    {
        int miao = d.ciao * 2;
        // do whatever with miao or d.ciao...
    }
}

public class C : A
{
    public DataC : IData
    {
        public float arrivederci;
    }

    public override void DoSomething<T>(T data) where T : DataC
    {
        int bau = d.arrivederci * 2f;
        // do whatever with bau or d.arrivederci...
    }
}

So, basically, override the generic constraint I did set in the parent's abstract generic method. Is there a way to achieve this?

Please note: I don't want to create a generic class but only a generic method that is able to get the right type of data per each different implementation of the base class.

7
  • 2
    This could not be valid: you've promised that DoSomething will accept any IData in A. You can't go and change your mind in B or C to only accept more derived types, even if constraints where variant in any way (which they're not). Consider carefully what kind of type safety (if any) you're really trying to achieve, here. Typically, this kind of design often means that you're setting up an inheritance hierarchy you actually don't want, but is better done through extension methods, concrete classes or (if really necessary) new methods and explicit downlevel casts in derived classes. Commented Apr 9, 2020 at 17:06
  • Try putting the type parameter on the A class instead of on the DoSomething method Commented Apr 9, 2020 at 17:18
  • 1
    Does this answer your question? Force derived class to implement interface Commented Apr 9, 2020 at 17:19
  • In public abstract class A() the () is invalid. Can you correct the code to make it valid C#? Commented Apr 9, 2020 at 17:28
  • 1
    The language simply doesn't allow this. See: learn.microsoft.com/en-us/dotnet/csharp/misc/cs0460 Commented Apr 10, 2020 at 8:01

2 Answers 2

0

Apparently what I'm trying to achieve is currently not possible in C#. After waiting for a while to see if there was a workaround I decided to quote JasperKent's comment as the definitive answer:

The language simply doesn't allow this. See: learn.microsoft.com/en-us/dotnet/csharp/misc/cs0460

Sign up to request clarification or add additional context in comments.

Comments

0

apparently it's not supported as you coded. But you may try a different coding like this:

public abstract void DoSomething<T, TConstraint>(T data) where T : TConstraint;

....

public override void DoSomething<T, DataB>(T data){ //your code here; }
....

public override void DoSomething<T, DataC>(T data){ //your code here; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.