2013-03-09 18 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 nie implementuje Stage zatem ani TIn ani TOut mogłoby kiedykolwiek być object, prawda? Dlaczego więc kompilator myśli, że PipelineElement<object, object> i PipelineElement<TIn, TOut> może stać się identyczny?Dlaczego powoduje to CS0695?

EDIT: Tak, to jest całkiem możliwe, aby wdrożyć te same rodzajowy interfejs wielokrotnie:

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

usunąłem moje komentarze, nie mam nic pożytecznego. Oznaczony jako ulubiony, chciałbym również znać odpowiedź :). +1 na pytanie! – bas

Odpowiedz

7

Od Compiler Error CS0695

'typ rodzajowy' nie może realizować zarówno 'interfejs rodzajowe' i „generic interfejs ', ponieważ mogą ujednolicić dla niektórych podstawień parametrów podstawień.

Ten błąd występuje ogólna klasa realizuje więcej niż jeden parametryzację samego interfejsu ogólnym i istnieje na zmianę parametru typ, który może sprawić, że dwa interfejsy identyczne. Aby uniknąć tego błędu, zaimplementuj tylko jeden z interfejsów, zmień parametry typu, aby uniknąć konfliktu.

Nie można implementować interfejsów PipelineElementBase<TIn, TOut> i PipelineElement<object, object> w klasie abstrakcji.

Zgodnie ze stroną błędu, powinieneś;

  • Wdrożenie tylko jednego z nich lub
  • zmienić parametry typu, aby uniknąć konfliktu.

Od C# 5.0 Language Specification

13.4.2 Wyjątkowość wdrożonych interfejsów

Interfejsy realizowane przez ogólny deklaracji typu musi pozostać wyjątkowy dla wszystkich możliwych typów budowanych. Bez tej reguły nie byłoby możliwe ustalenie prawidłowej metody wywoływania niektórych typów zbudowanych w postaci .Na przykład, załóżmy, że ogólny deklarację klasy pozwolono być napisane w sposób następujący:

interface I<T> 
{ 
    void F(); 
} 
class X<U,V>: I<U>, I<V> 
{ 
    void I<U>.F() {...} 
    void I<V>.F() {...} 
} 

Były to dozwolone, to byłoby niemożliwe, aby określić, który kod do wykonać w następujących przypadkach:

I<int> x = new X<int,int>(); 
x.F(); 

Aby ustalić, czy lista interfejs rodzajowy deklaracji typu jest 0.123.obowiązują następujące kroki wykonywane są:

  • Niech L będzie lista interfejsów bezpośrednio określonych w ogólnej klasy struct lub deklaracja interfejsu C.

  • Dodaj do L żadnych interfejsów podstawy interfejsy już L.

  • Usuń wszystkie duplikaty L.

  • Jeżeli ewentualne wykonana typu utworzony z C by po argumenty typu są podstawiane L, powoduje, że dwa interfejsy w L są identyczne, wtedy deklaracja C jest nieważna. Ograniczenia deklaracje nie są brane pod uwagę przy ustalaniu wszystkich możliwych typów konstrukcyjnych .

W zgłoszeniu klasy X powyżej lista graniczna L składa I<U> i I<V>. Deklaracja jest nieważna, ponieważ każdy skonstruowany typ z U i V jest tego samego typu, spowoduje, że te dwa interfejsy będą identyczne.

Jest możliwe dla określonych interfejsów na różnych poziomach od spadków aby ujednolicić:

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() {…} 
} 

Ten kod jest ważny, chociaż Derived<U,V> realizuje zarówno I<U> i I<V>. Kod

I<int> x = new Derived<int,int>(); 
x.F(); 

wywołuje sposób w Derived, ponieważ Derived<int,int> skutecznie ponowne narzędzia I<int> (§13.4.6).

[podkreślenie przez redaktora SO.]

+0

Jaki konflikt? W przypadku tych ograniczeń typu '' i '' nie mogą się kolidować. –

+5

@ main-- "Deklaracje o ograniczeniach nie są brane pod uwagę przy określaniu wszystkich możliwych typów konstrukcji." To jest kluczowy element twojego problemu, ale ta odpowiedź zakopuje to ważne zdanie w sposób zbyt szczegółowy IMHO. –

Powiązane problemy