2010-05-13 12 views

Respuesta

7

ambos serán equivalentes desde el punto de vista del rendimiento. Tiendo a preferir == sobre .Equals() para legibilidad, pero la belleza de L2S es que puedes usar cualquiera de ellos, dependiendo del tipo de objeto que tengas.

(Y estoy asumiendo que su segunda declaración está en la orderId, y no el objeto orden)

+0

No he hecho C# en años, pero ¿no es esto una cosa de autoboxing, y no de L2S? ¿O el '==' depende de la instancia en cuestión? –

+0

@yar: no se almacena nada, es un árbol de expresiones que se visita y se transforma en una consulta SQL. – Aaronaught

+0

@Aaronaught, sí, veo que ahora, desearía haber analizado el código con más cuidado :) Al mismo tiempo, tendré que leer en los árboles de expresiones, porque pensé que el "param" sería evaluado antes de que FirstOrDefault incluso lo consiga. Aparentemente eso no está bien. –

9

Voy a tratar de convencerte de que:

  • Los dos métodos que se proponen dar el mismo rendimiento
  • Existen al menos dos motivos relacionados con la falta de rendimiento que debería preferir ==.
  • Hay otra mejora por separado que puede realizar en su código para reducir la posibilidad de errores.

Para ver que el rendimiento será el mismo, consulte el SQL generado en cada caso. Este programa de prueba que muestra cómo se puede ver el SQL generado:

int orderId = 4; 
TextWriter textWriter = new StringWriter(); 
using (var dc = new DataClasses1DataContext()) 
{ 
    dc.Log = textWriter; 
    Order o1 = dc.Orders.FirstOrDefault(x => x.OrderId == orderId); 
    Order o2 = dc.Orders.FirstOrDefault(x => x.OrderId.Equals(orderId)); 
} 
string log = textWriter.ToString(); 

El SQL enviada en cada caso es el mismo, como se puede ver mediante la inspección del registro:

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description] 
FROM [dbo].[Order] AS [t0] 
WHERE [t0].[OrderId] = @p0 

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description] 
FROM [dbo].[Order] AS [t0] 
WHERE [t0].[OrderId] = @p0 

En cuanto a si se debe utilizar == o Equals, en primer lugar, sugiero usar == para facilitar la lectura. Esta es la forma idiomática de comparar dos enteros en C#.

En segundo lugar con == obtendrá un error de tiempo de compilación si proporciona objetos de tipos diferentes (incompatibles). Supongo que en su caso order tiene tipo int, pero supongamos que alguien más escribió este código y accidentalmente cometió un error donde order es una variable de tipo Order en lugar de int. Ahora vamos a comparar lo que sucedería en cada caso:

Order order = new Order { OrderId = 4 }; 

x.OrderId.Equals(order) // This compiles, but you get an exception at runtime: 
         // Could not format node 'Value' for execution as SQL. 

x.OrderId == order  // Compile error: Operator '==' cannot be applied to 
         // operands of type 'int' and 'Order' 

Es mejor obtener errores de compilación en tiempo de ejecución que los errores, por lo que prefieren utilizar == en este caso.

Finalmente, si solo espera un resultado, debería preferir usar SingleOrDefault en lugar de FirstOrDefault, ya que el primero arrojará una excepción si se encuentran dos objetos coincidentes en lugar de simplemente devolver el primero. Este control extra costará una pequeña cantidad en rendimiento, pero nuevamente le permite detectar los errores antes. Si el rendimiento es un problema crítico para usted, en lugar de eliminar estas comprobaciones de seguridad debería considerar buscar varios objetos de la base de datos a la vez, no un objeto a la vez.

Así que en resumen recomiendo que utilice esta:

Album album = db.Albums.SingleOrDefault(x => x.OrderId == orderId); 
+0

quiero decir que la orden tiene int tipo – Sasha

+3

¡Buen punto en .Equals() demasiado permisivo con los tipos! –

+0

+1 Gran respuesta Mark! –

1

En la mayoría de las situaciones que debe obtener el mismo resultado. Sin embargo, hay una diferencia.

El uso del operador Equals determina si dos instancias de objeto son iguales. El operador == determina si dos Objetos tienen el mismo valor.

En este caso, uso el operador ==, por lo que es más legible.

+3

+1 Buen punto. Si OrderId en el DB es nulo, ¿traducirá este L2S a 'x.Order == null'? Si es así, la llamada '.Equals' fallará ya que no hay ningún objeto válido en el lado izquierdo. –

+0

'Int32',' Guid', y todos los demás tipos de valores/primitivas tienen sobrecargas 'Iguales' que toman argumentos del mismo tipo. La única instancia en que esto produciría un resultado diferente es si el argumento 'orderId' es en realidad un tipo diferente de la propiedad' Order.OrderId'. – Aaronaught

+0

Esto es incorrecto: el método Equals se marca como virtual en System.Object y se puede sobrescribir. Debería hacer lo mismo que ==. –

0

Es casi lo mismo. Si desea comprobar sólo el valor, entonces debería usar

==

Si desea comprobar el valor, así como si son iguales o no casos utilizan

Iguales

Pero en ambos casos el tiempo resultante es casi el mismo.

+2

'Igual' no implica igualdad de referencia. Es * puede * realizar una verificación de referencia cuando los argumentos son ambos tipos de referencia, pero en gran medida es lo mismo que '==' a ese respecto. Si desea igualdad de referencia, utilice el método 'object.ReferenceEquals'. – Aaronaught