Esta es una característica particularmente confusa de C#. Aquí está el trato.
A lo largo de esta explicación suponemos que el tipo de elemento de una matriz es un tipo de referencia, no un tipo de valor.
C# admite insegura matriz covarianza. Eso significa que si tiene una matriz de cadena, puede convertirlo en una gran variedad de objetos, ya que una cadena se puede convertir en un objeto:
string[] a1 = { "hello", "goodbye" };
object[] a2 = a1; // Legal
Si a continuación, intenta obtener un elemento de a2, funciona:
object o3 = a2[0];
Eso es legal porque es realmente a2[0]
a1[0]
, que es una cadena, que es convertible a objetar.
Sin embargo, si se intenta escribir a la matriz entonces obtendrá un error en tiempo de ejecución :
a2[0] = new object();
Esta falla en tiempo de ejecución porque a2
es realmente una matriz de cadenas, y no puede poner un no-cadena en una matriz de cadenas.
Así que C# ya está horriblemente roto; es posible escribir un programa que compila y se ve normal, pero de repente falla con una excepción de tipo en el tiempo de ejecución porque trataste de poner un objeto en una matriz de objetos que en realidad no es una matriz de objetos.
La función que desea es aún más rota que la, y gracias a Dios C# no la admite. La función que desea es:
object[] a4 = { "Hello" };
string[] a5 = a4;
Eso sería peligroso arsenal contravarianza. Se rompe horrible como esto:
a4[0] = new Customer(); // Perfectly legal
string s6 = a5[0];
Y ahora que acabamos de copiar un cliente en una variable de tipo cadena .
Debe evitar cualquier tipo de matriz de covarianza o contravarianza; la contravariancia de matriz es, como usted ha descubierto, no legal, y la covarianza de matriz está haciendo pequeñas bombas de tiempo en su programa que se activan inesperadamente. Haga sus matrices del tipo correcto para comenzar.
¿Cómo está generando su matriz? ¿Como un todo? Necesita lanzar cada elemento de su matriz individualmente. – Msonic
Sí, claramente lo está lanzando como un todo. –
Varianza de matriz de referencia es a la inversa; puedes lanzar algo que es ** en realidad ** a 'string []' como 'object []', pero para ir hacia el otro lado debe ser en realidad una 'cadena []' –