2013-03-09 115 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

相關問題