2010-02-21 14 views
8

De acuerdo con la MSDN:"==" Operador no se comporta como iguales generados por el compilador() Accionamiento para Anonymous tipo

Debido a que los Iguales y GetHashCode métodos en los tipos anónimos se definen en términos de Equals y GetHashcode de las propiedades, dos instancias de del mismo tipo anónimo son iguales a si todas sus propiedades son iguales.

Sin embargo, el código siguiente muestra la ejecución generado por el compilador para Equals() no se comporta como se esperaba .:

DateTime start = new DateTime(2009,1,1); 
DateTime end = new DateTime(2010, 12,31); 

// months since year 0 
int startMonth = start.Date.Year * 12 + start.Date.Month - 1; 
int endMonth = end.Date.Year * 12 + end.Date.Month -1 ; 

// iterate through month-year pairs 
for (int i = startMonth; i <= endMonth ; i++) 
{ 
    var yearMonth = new { Year = (int)Math.Truncate(i/12d), Month = (i % 12) + 1}; 

    if (yearMonth.Year == 2009 && yearMonth.Month == 2) 
    Console.WriteLine("BOOM"); 

    if (yearMonth == new{Year = 2009, Month = 2}) 
    Console.WriteLine("I'm never called!"); 

    Console.WriteLine(yearMonth); 
} 

Me estoy perdiendo algo? Estoy mirando el MSIL generado pero no veo un error obvio. ¿Hay alguna forma de depurar el nivel de MSIL (además de WinDbg)? ¿Estoy pasando por alto algo?

He probado .NET 3.5 (compilador VS 2008 SP1). Como referencia, aquí está el método equals generada:

public override bool Equals(object value) 
{ 
    var type = value as <>f__AnonymousType3<<Year>j__TPar, <Month>j__TPar>; 
    return (((type != null) && EqualityComparer<<Year>j__TPar>.Default.Equals(this.<Year>i__Field, type.<Year>i__Field)) && EqualityComparer<<Month>j__TPar>.Default.Equals(this.<Month>i__Field, type.<Month>i__Field)); 
} 

Respuesta

7

== no es Equals() - Creo que el código debe funcionar como se espera cuando se hace esto:

if (yearMonth.Equals(new{Year = 2009, Month = 2})) 

Véase también this SO question.

6

Lucero tiene razón, pero quiero añadir una explicación de por qué es correcto.

Para tipos de referencia en .Net, el operador == está destinado a indicar referencia igualdad; ¿Dos variables se refieren a la misma instancia exacta de un objeto?

El método .Equals(), por otro lado, está destinado a indicar valor igualdad; ¿Las dos (probablemente) diferentes instancias de un objeto tienen el mismo valor, para alguna definición de "lo mismo" que normalmente se le permite proporcionar para sus tipos?

+3

... con la excepción habitual, el tipo 'string', que también se compara con igualdad de valor cuando se usa' == '(en contraste con Java);) – Lucero

+0

argh! (abofeteándome la frente) Me olvidé de eso. DIOS MIO. –

Cuestiones relacionadas