英文:
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<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
得分: 1
类型参数只是标识符。与声明变量的方式类似,如 int[][] array = ...
而不是 int array[][] = ...
。更正类型参数的名称将导致以下结果:
public override Object2[][] Export<Object1, Object2>(Object1[][] input) {
throw new System.NotImplementedException();
}
然而,仍然存在一个错误,error CS0115: 'DerivedClass.Export<Object1, Object2>(Object1[][])':找不到适合的方法来重写。
这是因为原始方法返回 Output
,仅返回 Output
,但重写方法返回 Output[][]
,这不匹配。相同的逻辑适用于 Input
和 Input[][]
。
最后的问题是设计问题:重写的方法不能比被重写的方法更加限制,因为这会违反多态性等原则。任何解决方案都必须在功能或备选设计方面做出妥协。
一个可能的解决方案是使用条件检查,然后委托给更加限制的方法。然而,在返回值方面必须做出妥协,因为原始方法只接受一个 Output
,而不是一个输出数组。
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)
{
// 代码
}
}
英文:
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
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论