2010-10-27 17 views
52

Dado el siguiente código, ¿cuál es la diferencia entre la forma en que se inicializa position0 y la forma en que se inicializa position1? ¿Son equivalentes? Sí no, ¿Cuál es la diferencia?¿Qué hacen los refuerzos después de la nueva declaración C#?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Position position0 = new Position() { x=3, y=4 }; 

     Position position1 = new Position(); 
     position1.x = 3; 
     position1.y = 4; 
    } 
} 

struct Position 
{ 
    public int x, y; 
} 

Respuesta

41

Iniciales de objetos y colecciones, utilizados para inicializar campos en un objeto.

http://msdn.microsoft.com/en-us/library/bb384062.aspx

Ellos producen casi equivalente IL. Jon Skeet tiene la respuesta sobre lo que realmente está pasando.

+1

Mucha verdad a eso. Publicé mi respuesta ... vi su respuesta, la edité para señalar su respuesta. –

+0

Jon Skeet parece responder todas las preguntas de este sitio :) No puedo esperar a leer su nuevo libro (si alguna vez lo publica realmente) – Bryan

1

Estos son totalmente equivalentes. El compilador simplemente transforma la primera versión en la segunda.

La única diferencia entre los dos es que con la primera, se puede hacer agradables adelgaza, como pasar a la versión inicializado a un método:

DoSomethingWithPoint(new Position() { x=3, y=4 }); 

Esto es mucho más líneas de código que el segundo inicialización ejemplo.

2

Sus dos muestras de código generarán IL idéntica. (Al menos en compilaciones de Release)

5

Es un inicializador de objetos, y simplemente le permite asignar valores en una sola expresión. Lo más importante, esto también funciona dentro de LINQ an para tipos anónimos (de lo contrario inmutables). También hay una sintaxis similar de inicialización de colección para elementos adicionales a colecciones nuevas.

Tenga en cuenta que hay un problema de tiempo sutil que puede ser útil; con los inicializadores, las asignaciones/agregaciones suceden antes de se asigna la variable, lo que puede ayudar a evitar que otros subprocesos vean un objeto incompleto. De lo contrario, necesitaría una variable adicional para lograr el mismo resultado.

+0

Joshua y Slaks publicaron que ambas formas de inicializar 'Posición' producen IL equivalente. ¿Estás diciendo que con tipos anónimos, obtendría un resultado diferente? –

+0

@rice - sí: solo uno de ellos compilaría :) –

1

Son equivalentes, aparte de que uno es más fácil de leer que el otro.

Ten en cuenta también el caso cuando se desea pasar el nuevo objeto a lo largo de otro lugar:

var aList = new List<Position>(); 
aList.Add(new Position() { x=3, y=4 }); 
51

No son bastante equivalente - al menos no en el caso general. El código utilizando un inicializador de objeto está más cerca de este:

Position tmp = new Position(); 
tmp.x = 3; 
tmp.y = 4; 
Position position1 = tmp; 

En otras palabras, la asignación a la variable sólo se produce después de las propiedades se han establecido. Ahora, en el caso de que esté declarando una nueva variable local, eso en realidad no importa, y el compilador puede optimizar su primer formulario. Pero, lógicamente, sí importa. Considere:

Position p1 = new Position { x = 10, y = 20 }; 

p1 = new Position { x = p1.y, y = p1.x }; 

Si eso hicieron la tarea de p1primera, acabaría con 0 tanto para p1.x y p1.y. Mientras que eso es realmente equivalente a:

Position tmp = new Position(); 
tmp.x = 10; 
tmp.y = 20; 
Position p1 = tmp; 

tmp = new Position(); 
tmp.x = p1.y; // 20 
tmp.y = p1.x; // 10 
p1 = tmp; 

EDIT: Me acabo de dar cuenta de que estás usando una estructura en lugar de una clase.Eso puede hacer algunas diferencias sutiles ... pero es casi seguro que no deberías estar usando una estructura mutable para empezar :)

2

Olvidando todas las cosas de IL, es solo una notación abreviada. Lo que está haciendo es esto:

a. En un caso, está utilizando explícitamente el constructor predeterminado y luego establece las dos propiedades.

b. En el otro, está utilizando la nueva sintaxis de inicializador que implícitamente hace que el compilador haga lo que hizo en el caso a.

A pesar de las subestigaciones de IL, lograrán lo mismo para usted.

Cuestiones relacionadas