2013-03-09 3 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?

EDIT: Да, это вполне возможно реализовать те же общий интерфейс несколько раз:

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

Я удалил мои комментарии, я не получил ничего полезного. Отмечено как фаворит, я тоже хотел бы узнать ответ :). +1 за вопрос, хотя! – bas

ответ

7

От Compiler Error CS0695

«универсальный тип» не может реализовать как «общий интерфейс» и «общий interface ', потому что они могут унифицировать для некоторого параметра типа замен.

Этой ошибка возникает, когда общий класс реализует более одного параметризации одного и тот же общего интерфейс, и существует подстановка параметра а типа, который сделал бы два интерфейса идентичен. Чтобы избежать этой ошибки, используйте только один из интерфейсов: или измените параметры типа, чтобы избежать конфликта.

Вы не можете использовать интерфейсы 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(); 

Чтобы определить, есть ли список интерфейсов декларации общего типа является действительно, выполняются следующие шаги:

  • Пусть Ь список интерфейсов, непосредственно указанных в общем классе, структуре или объявление интерфейса 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.]

+0

Какой конфликт? С этими ограничениями типа '' и '<объект, объект>' не могут столкнуться. –

+5

@ main-- «При определении всех возможных построенных типов не учитываются декларации ограничений». Это основной вопрос вашей проблемы, но этот ответ похоронит это важное предложение слишком много деталей IMHO. –

Смежные вопросы