Considere la definición de interfaz contravariante con un delegado:
public interface IInterface<in TInput> { delegate int Foo(int x); void Bar(TInput input); void Baz(TInput input, Foo foo); } La definición de Baz falla con un error:
CS1961
Varianza no válida: el parámetro de tipo 'TInput' debe ser covariantemente válido en 'IInterface<TInput>.Baz(TInput, IInterface<TInput>.Foo)'. 'TInput' es contravariante.
Mi pregunta es ¿por qué ? A primera vista, esto debería ser válido, ya que el delegado de Foo no tiene nada que ver con TInput . No sé si es que el compilador es demasiado conservador o si me estoy perdiendo algo.
Tenga en cuenta que normalmente no declararía un delegado dentro de una interfaz, en particular, esto no se compila en versiones anteriores a C# 8, ya que un delegado en una interfaz necesita implementaciones de interfaz predeterminadas.
¿Hay alguna manera de romper el sistema de tipos si se permitiera esta definición, o el compilador es conservador?
No estoy seguro de si se trata de un problema de covarianza frente a contravarianza.
Foo no es miembro de la interfaz. Es una declaración de tipo anidado.IInterface<A>.Foo e IInterface<B>.Foo son dos tipos diferentes.foo de dos IInterface<T>.Baz (con T = A y B ) sea incompatible.IInterface<A> por una IInterface<B> o viceversa (sin importar cuál sea la relación de herencia entre A y B ).IInterface<T> no puede ser variante (ni co- ni contra-).Resolución:
IInterface no genérica para esto (y conservar la genérica).Pero @EricLippert ciertamente lo sabe mejor.