2008-11-28 13 views
6

Tengo una pregunta sobre el uso de new[].C# Uso de nuevo []

Imagínese esto:

Object.SomeProperty = new[] {"string1", "string2"}; 

Dónde SomeProperty espera una matriz de cadenas.

Sé que este fragmento de código funcionará. Pero quiero saber lo que hace bajo el capó. ¿Hace new[] una instancia de la clase object y en SomeProperty lo convierte automáticamente en un objeto string?

Gracias

Respuesta

16

Bien, todavía hay un pequeño poco confuso aquí.

La inferencia que está sucediendo no tiene nada que ver con el tipo de Object.SomeProperty, pero todo tiene que ver con los tipos de las expresiones en el inicializador de la matriz. En otras palabras, podría hacer:

object o = new[] { "string1", "string2" }; 

y o seguiría siendo una referencia a una matriz de cadenas.

Básicamente, el compilador se ve en una expresión como la siguiente:

new[] { A, B, C, D, ... } 

(donde A, B, C, D, etc. son expresiones) y trata de resolver el tipo de matriz correcta para su uso. Solo considera los tipos de A, B, C y D (etc.) como el tipo de elemento de matriz. Tomando este conjunto de tipos de candidatos, trata de encontrar uno al que todos los demás puedan convertirse implícitamente. Si no hay exactamente un tipo, entonces el compilador se quejará.

Así, por ejemplo:

new[] { new Form(), new MemoryStream() } 

no se compilará - ni MemoryStream ni Form es convertible a la otra. Sin embargo:

new[] { GetSomeIDisposable(), new MemoryStream() } 

será tratado como un IDisposable[] porque hay una conversión implícita MemoryStream-IDisposable. Del mismo modo:

new[] { 0, 1, 3.5 } // double[] 
new[] { 1, 3, 100L } // long[] 
15

Esto es azúcar sintáctico. El compilador inferirá el tipo realmente necesario aquí y crear un código que es equivalente a la construcción explícita:

Object.SomeProperty = new string[] {"string1", "string2"}; 

No hay tal cosa como new[] que se ejecuta en tiempo de ejecución.

2

El compilador sustituye:

Object.SomeProperty = new[] {"string1", "string2"}; 

con:

Object.SomeProperty = new string[] {"string1", "string2"}; 
+0

Object.SomeProperty = {"string1", "string2"}; ¡No figura en ningún compilador de C#! Solo puedes hacer eso durante la inicialización. – leppie

+0

inicialización, siendo la inicialización variable. p.ej. string [] foo = {"bar", "baz"}; – leppie

+0

@leppie, aboslutamente a la derecha. Me corresponde corregido –

3

Se traduce más o menos a:

string[] $temp = new string[2]; 
$temp[0] = "string1"; 
$temp[1] = "string2"; 
Object.SomeProperty = $temp; 

Curiosamente, var x = new[] { "string1", "string2" }; obras, así, se puede inferir x estar a string[], pero var x = { "string1", "string2" }; falla.

+0

Eso es porque una matriz es un tipo de referencia que debe asignarse con nueva. Nada lo eliminará sintácticamente. –

+0

Sí, pero cuando se les da un tipo, no la nueva '[] 'noticias sintaxis hasta el tipo, pasando el IEnumerable , por lo que cuando sólo tiene var, por eso no podía durar por defecto zanja a T []? –

1

Espero que por su respuesta no se confunda entre la sustitución de tipo y la inferencia de tipo aquí. Supongo que el tipo de Object.SomeProperty es string [], aunque debido a la covarianza de la matriz podría ser objeto [] (tenga en cuenta que esto sería no sea una buena cosa - consulte Eric Lippert's post sobre este tema!).

El compilador realiza la inferencia de tipos usando una heurística - determina que "texto1" y "texto2" son de tipo cadena, y por lo tanto se reemplaza con eficacia su código con: -

Object.SomeProperty = new string[] {"string1", "string2"}; 

Realmente es tan simple ¡como eso! Todo se hace en tiempo de compilación, nada en tiempo de ejecución.