10
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,因此TInTOut不可能object,对吧?那么为什么编译器会这样认为PipelineElement<object, object>并且PipelineElement<TIn, TOut>可以变得相同呢?

编辑:是的,完全有可能多次实现相同的通用接口:

public interface MyInterface<A> { }
public class MyClass: MyInterface<string>, MyInterface<int> { }
4

1 回答 1

10

Compiler Error CS0695

“通用类型”不能同时实现“通用接口”和“通用接口”,因为它们可能会针对某些类型参数替换进行统一。

当泛型类实现同一个泛型接口的多个参数化并且存在使两个接口相同的类型参数替换时,会发生此错误。为避免此错误,请仅实现其中一个接口,或更改类型参数以避免冲突。

您不能同时实现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 编辑强调。]

于 2013-03-09T23:10:08.267 回答