validar tipos tipo serializar serializacion objeto dato convertir anonimos c# .net string equality string-interning

serializar - tipos anonimos c#



¿Cuál es el propósito de convertir en tipo "objeto"? (4)

He encontrado el código en un sitio web que es el siguiente.

string a = "xx"; string b = "xx"; string c = "x"; string d = String.Intern(c + c); Console.WriteLine((object)a == (object)b); // True Console.WriteLine((object)a == (object)d); // True

Aquí, ¿cuál es el propósito de convertir de nuevo en tipo de objeto ya que a, b, d son en sí mismos los objetos de una cadena?


C # usa el token == para representar tres operadores distintos: un operador de verificación de igualdad recargable (que se puede usar en tipos de clase o tipos de valor si existen sobrecargas para los tipos exactos en cuestión), un operador de verificación de identidad de referencia no recargable (que requiere que ambos operandos sean referencias de clase y requiere que los tipos no sean mutuamente excluyentes, y un operador de comprobación de nulos (que se puede usar con cualquier tipo de clase, tipo de valor que pueda contener nulos o genéricos que puedan ser uno de los anteriores). Si bien la mayoría de las formas de sobrecarga se definen de manera uniforme en todos los lenguajes .NET, el uso de un operador para los tres tipos de igualdad no lo es. Otros lenguajes como VB.NET usan un token diferente para la primera forma (por ejemplo, en VB.NET, la expresión (x = y) usa una sobrecarga de prueba de igualdad si está definida, o genera un error de sintaxis si no es así) (x Is y) comprueba si x e y identifican la misma instancia de objeto sin tener en cuenta si existe un operador de igualdad sobrecargado).

El propósito de los lanzamientos a Object es asegurar que el token == sea ​​interpretado como un operador de verificación de identidad de referencia en lugar de un operador de igualdad sobrecargable; dichos lanzamientos son necesarios solo por la forma en que C implementa el operador == , y no sería necesario en otros idiomas como VB.NET.


Comentar con el código

Por lo tanto, si los valores "xx" se establecieron en tiempo de ejecución, todos al mismo valor de "xx", obtendría un resultado falso diferente, ya que el compilador no tuvo la oportunidad de realizar la optimización en tiempo de ejecución, aunque sea el mismo código y valores de entrada en ambos casos, resultados diferentes para precompilado frente a tiempo de ejecución.

private void button1_Click(object sender, EventArgs e) { string a = "xx"; string b = "xx"; string c = "x"; string d = String.Intern(c + c); Console.WriteLine((object)a == (object)b); // True Console.WriteLine((object)a == (object)d); // True } private void button2_Click(object sender, EventArgs e) { string a = textBox1.Text; //type in xx at runtime string b = textBox2.Text; //type in xx at runtime string c = textBox3.Text; //type in just "x" at runtime string d = String.Intern(c + c); Console.WriteLine((object)a == (object)b); // False with runtime values that have the same value Console.WriteLine((object)a == (object)d); // False Console.WriteLine(a == d); // True - the Equals Operator of the string works as expected still }


El compilador de C # intentará obtener todas las cadenas constantes en tiempo de compilación. Esto se llama internado de cadena . Entonces, después de que el código generado a y b sean referencias a la misma cadena que contiene "xx".

Puede verificar esto comparando sus referencias ( object.ReferenceEquals en objeto y hacer la verificación de igualdad o usar object.ReferenceEquals ). Tenga en cuenta que el operador == para cadenas compara sus valores y no sus referencias.

Otra cosa a mencionar es que las cadenas son inmutables en .NET.

string a = "xx"; string b = "x" + "x"; // String interning here string c = string.Join("", new[] { "x", "x" }); // No interning here because it is evaluated at runtime Console.WriteLine((object)a == (object)b); // True. Reference check Console.WriteLine(a == b); // True. Value check Console.WriteLine((object)a == c); //False. Reference check. Described below Console.WriteLine(a == c); // True. Value check

Entonces, ¿por qué es Console.WriteLine((object)a == c); haciendo una verificación de referencia? Porque el compilador elegirá el operador == en el objeto que verifica la igualdad de referencia.

Por lo tanto, el punto principal de la conversión de objetos para objetar en su pregunta es verificar si la internación de cadenas funciona o no. Suponiendo que no hay pasantía en el momento de la compilación .

string a = "xx"; string b = "xx"; string c = "x"; string d = String.Intern(c + c);

Luego Console.WriteLine((object)a == (object)b); imprimiría "Falso", porque a y b son referencias para dos cadenas de caracteres diferentes en la memoria, las cuales se parecen a "xx".


Una adición a la respuesta proporcionada: cadena (Referencia de C #)

La clase System.String es un tipo de referencia inmutable que se proporciona en la biblioteca de clases del framework .NET. Esta clase crea un nuevo objeto de cadena internamente para cualquier acción de manipulación de cadenas. El contenido de los objetos de este tipo no cambia, aunque la sintaxis hace que parezca que los contenidos pueden cambiarse. Además, la cadena se utiliza como clave de tabla hash para el cálculo de los valores de hash para evitar el riesgo de dañar la estructura de datos de hash.

Ejemplo:

string a = "hello"; string b = "h"; // Append to contents of ''b'' b += "ello"; // When you set the variable''s b value to "hello", // this would result in changing the pointer // to the object in the HEAP the variable "a" is already pointing to // Result would be: (reference of a == reference of b) --> TRUE // b = "hello"; Console.WriteLine(a == b); // value comparison Console.WriteLine((object)a == (object)b); // reference comparison Console.WriteLine (object.ReferenceEquals(a,b)); // reference comparison without casting

Resultado:

True False False

Explicación :

Esto creará un nuevo objeto:

string a = "hello";

Esto creará otro objeto:

string b = "h";

Esto creará otro objeto más:

b += "ello";

Lo siguiente creará una referencia a un objeto existente, más precisamente, apuntará al mismo objeto que la variable "a" apunta a → "hola".

string c = "hello"; Console.WriteLine (object.ReferenceEquals(a,c)); // --> TRUE

Las cadenas son inmutables: el contenido de un objeto de cadena no se puede cambiar después de que se crea el objeto , aunque la sintaxis hace que parezca que puedes hacerlo. Por ejemplo, cuando escribe este código, el compilador en realidad crea un nuevo objeto de cadena para contener la nueva secuencia de caracteres, y ese nuevo objeto se asigna a b. La cadena "h" es elegible para la recolección de basura.