public interface PipelineElement<in TIn, out TOut>
{
IEnumerable<TOut> Run(IEnumerable<TIn> input, Action<Error> errorReporter);
}
public interface Stage
{
}
public abstract class PipelineElementBase<TIn, TOut> : PipelineElement<object, object>,
PipelineElement<TIn, TOut> where TIn : Stage where TOut : Stage
{
IEnumerable<object> PipelineElement<object, object>.Run(IEnumerable<object> input, Action<Error> errorReporter)
{
return this.Run(input.Cast<TIn>(), errorReporter).Cast<object>();
}
public abstract IEnumerable<TOut> Run(IEnumerable<TIn> input, Action<Error> errorReporter);
}
object
未实现Stage
,因此TIn
和TOut
都不能object
,对吧?那么为什么编译器认为PipelineElement<object, object>
和PipelineElement<TIn, TOut>
可以变得相同?
编辑:是的,完全可以多次实现相同的通用接口:
public interface MyInterface<A> { }
public class MyClass: MyInterface<string>, MyInterface<int> { }
答案 0 :(得分:10)
'泛型类型'不能同时实现'通用接口'和'通用接口' 接口'因为它们可能统一某些类型参数 取代。
当泛型类实现多个时,会发生此错误 参数化相同的通用接口,并且存在一个 类型参数替换,它将构成两个接口 相同。要避免此错误,请仅实现其中一个接口, 或更改类型参数以避免冲突。
您不能同时为抽象类实现PipelineElementBase<TIn, TOut>
和PipelineElement<object, object>
接口。
正如错误页面所说,你应该;
来自C# 5.0 Language Specification
13.4.2已实现接口的唯一性
必须保留由泛型类型声明实现的接口 所有可能的构造类型都是唯一的没有这个规则,它会 无法确定正确的方法来确定 构造类型。例如,假设一个泛型类声明 被允许写成如下:
interface I<T>
{
void F();
}
class X<U,V>: I<U>, I<V>
{
void I<U>.F() {...}
void I<V>.F() {...}
}
如果允许,则无法确定要使用哪个代码 执行以下情况:
I<int> x = new X<int,int>();
x.F();
确定泛型类型声明的接口列表是否为 有效,执行以下步骤:
设L是通用类,结构或接口声明C中直接指定的接口列表。
将L中已有的接口的任何基接口添加到L。
- 中删除所有重复项
从L。
如果从C创建的任何可能的构造类型将在类型参数替换为L之后导致L中的两个接口为 相同,那么C的声明无效。的约束 在确定所有可能的情况时,不会考虑声明 构造类型。
在上面的类声明
X
中,接口列表L由I<U>
和I<V>
。声明无效,因为任何构造 类型为U
且V
类型相同会导致这两种类型 接口是相同的类型。可以在不同的继承中指定接口 统一水平:
interface I<T> { void F(); } class Base<U>: I<U> { void I<U>.F() {…} } class Derived<U,V>: Base<U>, I<V> // Ok { void I<V>.F() {…} }
即使
Derived<U,V>
同时实现I<U>
,此代码仍然有效 和I<V>
。代码I<int> x = new Derived<int,int>(); x.F();
有效地调用
Derived
中的方法,因为Derived<int,int>
重新实现I<int>
(§13.4.6)。
[SO编辑强调。]