validar objeto entre ejemplos diferente diferencia comparar cadenas c# .net clr

objeto - string.equals c#



En.NET 4.0, ¿cuál es la implementación predeterminada de Equals para los tipos de valor? (2)

Al no ser un verdadero experto en este campo, seguiría adelante y expondría mis pensamientos: la documentación (según yo) establece que si su estructura tiene un campo que es objeto, no se puede evitar la reflexión.

Así que si tienes lo siguiente:

public struct SomeStruct { public object ObjectTest }

El ObjectTest no puede compararse sin reflexión. Así se utilizará la reflexión. Esta parte del texto parece decir que tengo razón:

" ValueType.Equals : la implementación predeterminada del método Equals usa la reflexión para comparar los campos correspondientes de obj y esta instancia".

Las dos páginas de documentación parecen contradecir este tema:

  • El método ValueType.Equals dice "La implementación predeterminada del método Equals usa la reflexión para comparar los campos correspondientes de obj y esta instancia".
  • Object.Equals Method (Object) dice "La implementación predeterminada de Equals admite la igualdad de referencia para los tipos de referencia y la igualdad a nivel de bits para los tipos de valor ".

Entonces, ¿se trata de igualdad o reflexión a nivel de bit?

ValueType un vistazo al código fuente de ValueType y encontré un comentario que decía

// si no hay referencias GC en este objeto podemos evitar la reflexión

// y haz un memcmp rápido

¿Alguien puede aclarar qué significa "referencia GC"? Supongo que es un campo que tiene un tipo de referencia pero no estoy seguro.

Si creo una struct que solo tiene campos de tipo de valor, ¿las instancias de la misma se compararán siempre de forma rápida?

ACTUALIZACIÓN: La documentación para .Net 4.5 se ha mejorado significativamente: está libre de la contradicción mencionada y ahora ofrece una mejor comprensión de cómo funciona la verificación de igualdad de tipo de valor predeterminado.


ValueType es especial. Hace esto:

  1. Si el obj que se compara con es nulo, devuelve falso.
  2. Si los argumentos this y obj son de tipos diferentes, devuelve false.
  3. Utiliza la reflexión para llamar a Igual en cada campo de instancia para cada valor, si alguno de esos campos no es igual, devuelve falso. De lo contrario, devuelve true, nunca llama a ValueTypes base.Equals (que es object.Equals).

Debido a que utiliza la reflexión para comparar los campos, siempre debe anular los Equals en cualquier ValueType que cree. La reflexión es lenta.

Cuando se trata de una "referencia de GCR", o un campo en la estructura que es un tipo de referencia, termina utilizando la reflexión en cada campo para hacer la comparación. Tiene que hacer esto, porque la estructura en realidad tiene un puntero a la ubicación del tipo de referencia en el montón.

Si no se utiliza ningún tipo de referencia en la estructura, y son del mismo tipo, se garantiza que los campos estarán en el mismo orden y tendrán el mismo tamaño en la memoria, por lo que solo puede comparar la memoria disponible.

Para una estructura con solo tipos de valor para campos, es decir, una estructura con solo un campo int , no se realiza ninguna reflexión durante una comparación. Ninguno de los campos hace referencia a nada en el montón, por lo que no hay GCReference o GCHandle . Además, cualquier instancia de esta estructura tendrá el mismo diseño en memoria de los campos (con algunas excepciones menores), por lo que el equipo de CLR puede hacer una comparación de memoria directa (memcmp), que es mucho más rápida que la otra opción.

Así que sí, si solo tiene tipos de valor en su estructura, lo hará memcmp más rápido, en lugar de la comparación de reflexión, pero es posible que no quiera hacerlo. Sigue leyendo.

Esto no significa que debas usar la implementación por defecto. De hecho, no hagas eso. Para. Está haciendo comparaciones de bits, que no siempre son precisas. ¿Qué es lo que dices? Deja que te enseñe:

private struct MyThing { public float MyFloat; } private static void Main(string[] args) { MyThing f, s; f.MyFloat = 0.0f; s.MyFloat = -0.0f; Console.WriteLine(f.Equals(s)); // prints False Console.WriteLine(0.0f == -0.0f); // prints True }

Los números son iguales matemáticamente, pero no son iguales en su representación binaria. Por lo tanto, lo enfatizaré nuevamente, no confíe en la implementación predeterminada de ValueType.Equals