C# generics error when overriding with an array?

65 Views Asked by At

I've written an abstract method in C# (/Unity however I don't think that's the issue here) that I want to use to export objects using generic types. The problem i'm facing is it wont allow me to override the type input with a 2D array which is what this current implementation is expecting as input / output. Currently it errors when I put in the square brackets.

Generic method:

public abstract Output Export<Input, Output>(Input input);

Overriding method:

public override Object2[][] Export<Object1[][], Object2[][]>(Object1[][] input) {
    throw new System.NotImplementedException();
}

I've tried searching over the Microsoft documentation and i can't find any solutions to this problem or even a mention of the restriction.

Possible solutions I'm thinking of include writing a wrapper interface / class for the input / output. However I feel that is needlessly messy and will just be code bloat for something that can be done in another way that I don't know of.

TLDR: Using C# generics and it errors on the square brackets if I override the generic input/output with an array

1

There are 1 best solutions below

0
Xenohon On

Type parameters are simply identifiers. Similar to how one would declare variables in the manner int[][] array = ... rather than int array[][] = .... Correcting the type parameter names would result in

public override Object2[][] Export<Object1, Object2>(Object1[][] input) {
    throw new System.NotImplementedException();
}

However, one error still remains, error CS0115: 'DerivedClass.Export<Object1, Object2>(Object1[][])': no suitable method found to override. This is because the original method returns Output, and only Output, but the overriding method returns Output[][], which does not match. The same logic applies to Input and Input[][].

The last problem is design one: The overriding method can not be more restrictive than the overridden method, because it violates polymorphism among other things. Any solution will have to compromise in terms of feature or with an alternative design.

One possible solution is using an if check then delegating to the more restrictive method. However, a compromise has to be made in the return, because the original method only accepts one Output, rather than an array of outputs.

class DerivedClass : BaseClass
{
    public override Object2 Export<Object1, Object2>(Object1 input)
    {
        if (input is Object1[][] inputArray)
        {
            return Export<Object1, Object2>(inputArray).FirstOrDefault()?.FirstOrDefault();
        }
        else
        {
            return Export<Object1, Object2>(new Object1[][] { new Object1[] { input } }).FirstOrDefault()?.FirstOrDefault();
        }
    }

    public Object2[][] Export<Object1, Object2>(Object1[][] input)
    {
        // code
    }
}