2013-03-09 71 views
8
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>可以变得相同?为什么这会导致CS0695?

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

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

我打消了我的意见,我没有什么用处。标记为最喜欢的,我想知道答案以及:)。 +1的问题,虽然! – bas 2013-03-09 23:19:04

回答

7

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>和。该声明是无效的,因为任何构造的 类型与UV是相同的类型会导致这两个接口是相同的类型。

这是可能的,在不同的继承 层次分别规定统一的接口:

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编辑重点。]

+0

哪个冲突?通过这些类型约束,''和''不能相互冲突。 – 2013-03-09 23:11:12

+5

@ main--“在确定所有可能的构造类型时,不考虑约束声明。”这是你的问题的关键,但这个答案掩盖了这个重要的句子太多细节恕我直言。 – 2013-03-10 01:09:36