[英]Non-generic implementations of generic interfaces
I have the following group of 3 interfaces and 3 implementations of those said interfaces. 我具有以下3组接口和这些接口的3种实现。 The interfaces are defined with generics, and the topmost interface requires its parameter to extend the second one down; 接口是用泛型定义的,最顶层的接口需要其参数来向下扩展第二个接口; same with the second interface to the third. 与第二个界面到第三个相同。 The classes have no generic parameters and instead implement the interface with a specific class, each of which meets the requirements for the interface. 这些类没有通用参数,而是使用一个特定的类来实现接口,每个类都满足该接口的要求。
namespace GenericsIssueExample
{
interface IGroup<Row> where Row : IRow<IEntry>
{
Row[] Rows {
get;
set;
}
}
interface IRow<Entry> where Entry : IEntry
{
Entry[] Entries {
get;
set;
}
}
interface IEntry
{
int Value {
get;
set;
}
}
class ExampleGroup : IGroup<ExampleRow>
{
private ExampleRow[] rows;
public ExampleRow[] Rows {
get { return rows; }
set { rows = value; }
}
}
class ExampleRow : IRow<ExampleEntry>
{
private ExampleEntry[] entries;
public ExampleEntry[] Entries {
get { return entries; }
set { entries = value; }
}
}
class ExampleEntry : IEntry
{
private int val = 0;
public int Value {
get { return val; }
set { val = value; }
}
}
}
When I try to compile the above code, I get the following compile error: 当我尝试编译以上代码时,出现以下编译错误:
The type 'GenericsIssueExample.ExampleRow' cannot be used as type parameter 'Row' in the generic type or method 'GenericsIssueExample.IGroup<Row>'. There is no implicit reference conversion from 'GenericsIssueExample.ExampleRow' to 'GenericsIssueExample.IRow<GenericsIssueExample.IEntry>'.
This error is on line 27, which is the definition of ExampleGroup
: 此错误在第27行,它是ExampleGroup
的定义:
class ExampleGroup : IGroup<ExampleRow>
I don't understand why this is occurring, as ExampleRow
does implement IRow<IEntry>
. 我不明白为什么会这样,因为ExampleRow
确实实现了IRow<IEntry>
。 ( IRow<ExampleEntry>
). ( IRow<ExampleEntry>
)。
How would I correct the above code to resolve that error? 我将如何纠正上述代码来解决该错误?
Just because ExampleEntry
can be implicitly converted to an IEntry
does not mean that an IRow<ExampleEntry>
can be converted to an IRow<IEntry>
. 仅仅因为ExampleEntry
可以隐式转换为IEntry
并不意味着IRow<ExampleEntry>
可以转换为IRow<IEntry>
。 If IRow
is covariant with respect to its generic argument, then yes, that would be possible, but it's not as it stands, so the implicit conversion isn't possible. 如果IRow
相对于其通用参数是协变的,则可以,这是可能的,但事实并非如此,因此隐式转换是不可能的。
If you could implicitly convert an IRow<ExampleEntry>
to an IRow<IEntry>
then you could set the Entries
property to an array of an IEntry
type that is not an ExampleRow
. 如果你能隐式转换的IRow<ExampleEntry>
到IRow<IEntry>
那么你可以设置Entries
属性设置为一个数组IEntry
类型,它是不是一个ExampleRow
。
The problem is you're intermixing interfaces and generics where it is not applicable. 问题是您在不适用的地方混合了接口和泛型。 It's hard to see in your example but if you fix the naming convention so all generic type parameters are named TSomething
then it'll be clear. 在您的示例中很难看到,但是如果您修改了命名约定,那么所有通用类型参数都被命名为TSomething
那么这很清楚。
Once we do this, then it's clear we want to specify that we want a row of classes that implement IEntry
, not a row of IEntry
instances themselves. 完成此操作后,很明显,我们要指定我们要一行实现IEntry
的类,而不是一行IEntry
实例本身。
Here's a working example: 这是一个工作示例:
namespace GenericsIssueExample
{
interface IGroup<TRow, TEntry>
where TRow : IRow<TEntry>
where TEntry : IEntry
{
TRow[] Rows
{
get;
set;
}
}
interface IRow<TEntry> where TEntry : IEntry
{
TEntry[] Entries
{
get;
set;
}
}
interface IEntry
{
int Value
{
get;
set;
}
}
class ExampleGroup : IGroup<ExampleRow, ExampleEntry>
{
private ExampleRow[] rows;
public ExampleRow[] Rows
{
get { return rows; }
set { rows = value; }
}
}
class ExampleRow : IRow<ExampleEntry>
{
private ExampleEntry[] entries;
public ExampleEntry[] Entries
{
get { return entries; }
set { entries = value; }
}
}
class ExampleEntry : IEntry
{
private int val = 0;
public int Value
{
get { return val; }
set { val = value; }
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.