positiva - ¿Se rompe la covarianza en matrices C#?
matriz de covarianza interpretacion (1)
He compilado y probado el código dado en VS2010 usando .Net 4 en Windows 7 y funciona bien, no da una excepción de tiempo de ejecución, por lo que parece que su problema está relacionado con Mono o Unity.
Con el código dado es difícil hacer suposiciones sobre cuál es el problema. El tipo exacto de la excepción y algunos otros casos de prueba (es decir, las variaciones que no usan interfaces) ayudarían a reducir el problema exacto, pero eso es un asunto que debe resolver la comunidad Mono | Unity.
En cuanto a que está vinculado a ese artículo, no está relacionado.
Lo que el artículo describe es la siguiente situación:
class A { }
class B: A { }
class C: A { }
A[] a = new B[1];
a[0] = new C(); //<-- throws ArrayTypeMismatchException
Para simplificar lo que Eric está diciendo en su artículo:
a es una variable que puede contener una matriz de cualquier tipo que hereda de A.
a se le asigna una matriz de B, por lo tanto a es una matriz de B.
Cuando el usuario intenta asignar una nueva C a un elemento de a, hay una falta de coincidencia de tipos porque a es en realidad una matriz de B, por lo que asignar una C a un elemento de a es equivalente a tratar de asignar una nueva C a una variable que sostiene B como asi:
B b = new C();
Un problema similar surgiría de la asignación de una matriz de C.
Sin embargo, como a se define como ser capaz de mantener una matriz de A, el usuario podría asignar una matriz de A, lo que le permitiría aceptar ambos valores de B y C.
Es debido a esto que el código en su pregunta parece estar relacionado con este problema, pero en realidad no se debe a que se asigne como una matriz de ITest, por lo que debería ser capaz de almacenar tipos de ITest y que el error de tiempo de ejecución ser lanzado se deriva de un error en el tiempo de ejecución de Mono o Unity.
Considere la siguiente ITest
interfaz ITest
con un parámetro de tipo covariante T
, la Test
clase genérica que implementa la interfaz, y una clase A
y con una subclase B
:
interface ITest<out T>
{
T prop{ get;}
}
class Test<T> : ITest<T>
{
public T prop{ get {
return default(T);
}}
}
class A {
}
class B: A {
}
El siguiente código compila sin errores pero lanza la excepción de tiempo de ejecución System.ArrayTypeMismatchException
:
ITest<A>[] a = new ITest<A>[1];
a[0] = new Test<B>(); //<-- throws runtime exception
pero este código funciona bien:
ITest<A> r = new Test<B>();
Esto ha sido probado en Mono 2.10.2
( Unity3d 4.1
). Creo que esto está relacionado de alguna manera con la covarianza rota en los arreglos (vea http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx ).
No tengo claro por qué la comprobación de tipo que está ocurriendo cuando se asigna la ranura de matriz no está teniendo en cuenta la covarianza.