问题描述
我有以下一组接口的3个接口和3个实现。接口是用泛型定义的,最顶层的接口需要参数来扩展第二个接口;第二个界面与第三个界面相同。这些类没有泛型参数,而是实现了具有特定类的接口,每个接口都满足接口的要求。
$ b
namespace GenericsIssueExample
{
interface IGroup< Row>其中Row:IRow< IEntry>
{
行[]行{
get;
set;
}
}
interface IRow< Entry>其中条目:IEntry
{
条目[]条目{
get;
set;
}
}
接口IEntry
{
int值{
get;
set;
}
}
class ExampleGroup:IGroup< ExampleRow>
{
private ExampleRow [] rows;
public ExampleRow []行{
get {return rows; }
set {rows = value; }
}
}
class ExampleRow:IRow< ExampleEntry>
{
private ExampleEntry [] entries;
public ExampleEntry []条目{
get {return entries; }
set {entries = value; }
class ExampleEntry:IEntry
{
private int val = 0;
public int Value {
get {return val; }
set {val = value; }
}
}
}
当我尝试编译上面的代码中,我得到了下面的编译错误:
$ block
$ p $ c $类型'GenericsIssueExample.ExampleRow'不能用作泛型类型或方法'GenericsIssueExample.IGroup< Row>'中的类型参数'Row'。没有从'GenericsIssueExample.ExampleRow'到'GenericsIssueExample.IRow< GenericsIssueExample.IEntry>'的隐式引用转换。
此错误位于第27行,即 ExampleGroup
的定义:
class ExampleGroup:IGroup< ExampleRow>
我不明白为什么会发生这种情况,因为 ExampleRow
确实实现了 IRow< IEntry>
。 ( IRow< ExampleEntry>
)。
我如何纠正上述代码来解决这个错误?
问题在于你在不适用的地方混用了接口和泛型。在你的例子中很难看到,但如果你修复了命名约定,所以所有的泛型类型参数都被命名为 TSomething
,那么它就很清楚了。
一旦我们这样做了,那么很明显我们想要指定我们需要一行实现 IEntry
的类,而不是一行<$ c
下面是一个工作示例:
namespace GenericsIssueExample
{
interface IGroup< TRow,TEntry>
其中TRow:IRow< TEntry>
其中TEntry:IEntry
{
TRow []行
{
get;
set;
}
}
interface IRow< TEntry>其中TEntry:IEntry
{
TEntry []条目
{
get;
set;
}
}
接口IEntry
{
诠释值
{
get;
set;
}
}
class ExampleGroup:IGroup< ExampleRow,ExampleEntry>
{
private ExampleRow [] rows;
public ExampleRow []行
{
get {return rows; }
set {rows = value; }
}
}
class ExampleRow:IRow< ExampleEntry>
{
private ExampleEntry [] entries;
public ExampleEntry []条目
{
get {return entries; }
set {entries = value; }
class ExampleEntry:IEntry
{
private int val = 0;
public int Value
{
get {return val; }
set {val = value; }
}
}
}
I have the following group of 3 interfaces and 3 implementations of those said interfaces. 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:
This error is on line 27, which is the definition of ExampleGroup
:
class ExampleGroup : IGroup<ExampleRow>
I don't understand why this is occurring, as ExampleRow
does implement IRow<IEntry>
. (IRow<ExampleEntry>
).
How would I correct the above code to resolve that error?
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.
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.
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; }
}
}
}
这篇关于通用接口的非泛型实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!