C# 泛型在使用数组进行覆盖时出错?

huangapple go评论69阅读模式
英文:

C# generics error when overriding with an array?

问题

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

英文:

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&lt;Input, Output&gt;(Input input);

Overriding method:

public override Object2[][] Export&lt;Object1[][], Object2[][]&gt;(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

得分: 1

类型参数只是标识符。与声明变量的方式类似,如 int[][] array = ... 而不是 int array[][] = ...。更正类型参数的名称将导致以下结果:

public override Object2[][] Export&lt;Object1, Object2&gt;(Object1[][] input) {
    throw new System.NotImplementedException();
}

然而,仍然存在一个错误,error CS0115: 'DerivedClass.Export&lt;Object1, Object2&gt;(Object1[][])':找不到适合的方法来重写。 这是因为原始方法返回 Output,仅返回 Output,但重写方法返回 Output[][],这不匹配。相同的逻辑适用于 InputInput[][]

最后的问题是设计问题:重写的方法不能比被重写的方法更加限制,因为这会违反多态性等原则。任何解决方案都必须在功能或备选设计方面做出妥协。

一个可能的解决方案是使用条件检查,然后委托给更加限制的方法。然而,在返回值方面必须做出妥协,因为原始方法只接受一个 Output,而不是一个输出数组。

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

    public Object2[][] Export&lt;Object1, Object2&gt;(Object1[][] input)
    {
        // 代码
    }
}
英文:

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&lt;Object1, Object2&gt;(Object1[][] input) {
    throw new System.NotImplementedException();
}

However, one error still remains, error CS0115: &#39;DerivedClass.Export&lt;Object1, Object2&gt;(Object1[][])&#39;: 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&lt;Object1, Object2&gt;(Object1 input)
    {
        if (input is Object1[][] inputArray)
        {
            return Export&lt;Object1, Object2&gt;(inputArray).FirstOrDefault()?.FirstOrDefault();
        }
        else
        {
            return Export&lt;Object1, Object2&gt;(new Object1[][] { new Object1[] { input } }).FirstOrDefault()?.FirstOrDefault();
        }
    }

    public Object2[][] Export&lt;Object1, Object2&gt;(Object1[][] input)
    {
        // code
    }
}

huangapple
  • 本文由 发表于 2023年5月28日 11:42:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定