type objeto new initialize anonimo c# .net tostring anonymous-types

c# - objeto - ¿Cómo funciona ToString en un tipo anónimo?



objeto anonimo c# (3)

Estaba jugando con tipos anónimos, y accidentalmente lo puse en la consola. Se veía básicamente como lo definí.

Aquí hay un programa corto que lo reproduce:

using System; class Program { public static void Main(string[] args) { int Integer = 2; DateTime DateTime = DateTime.Now; Console.WriteLine(new { Test = 0, Integer, s = DateTime }); Console.ReadKey(true); } }

Ahora, la salida es:

{ Test = 0, Integer = 2, s = 28/05/2013 15:07:19 }

Intenté usar dotPeek para entrar en el ensamblaje y descubrir por qué, pero no sirvió de nada. [1] Aquí está el código dotPeek''d:

// Type: Program // Assembly: MyProjectName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null // Assembly location: Not telling you! :P using System; internal class Program { public static void Main(string[] args) { Console.WriteLine((object) new { Test = 0, Integer = 2, s = DateTime.Now }); Console.ReadKey(true); } }

Así que no es muy diferente, en absoluto.

¿Entonces, cómo funciona? ¿Cómo lo produce así?

Notas:

[1] : Olvidé activar "Mostrar código generado por compilador", esa es la razón por la que no entendí cómo funciona.


Con objetos anónimos ...

El compilador genera una clase interna sellada que modela el tipo anónimo. El tipo anónimo es inmutable; Todas las propiedades son de solo lectura. Esa clase contiene anulaciones de Equals () y GetHashCode () que implementan valores semánticos. Además, el compilador genera una anulación de ToString () que muestra el valor de cada una de las propiedades públicas.

Fuente: link

Por favor, verifique la respuesta de @Ilya Ivanov para ver un código sobre este tema.


Los tipos anónimos siguen siendo tipos totalmente definidos ... simplemente: el compilador los genera completamente por sí mismo, y nunca verá el nombre / implementación (solo: coincide con el inicializador que usa en su código).

En realidad, el ToString no se menciona con respecto a los tipos anónimos en la acción específica (sección 7.6.10.6); solo se requiere que Equals y GetHashCode funcionen en términos de las propiedades. El ejemplo en la especificación ("declara un tipo anónimo del formulario") no incluye una anulación ToString .

El compilador de MS agrega una implementación basada en propiedades de ToString como una cortesía , pero quizás también porque ToString predeterminado es el nombre de tipo, que por sí mismo no tendría sentido (es, después de todo, anónimo). El nombre de tipo es bastante horrible de leer. , e incluye sintaxis de genéricos). Francamente, sería una buena idea usar esto solo para fines de depuración.


Solo para agregar algo de código a la respuesta de HuorSwords, el compilador generará el método ToString para su ejemplo, como se indica a continuación:

public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{ Test = "); stringBuilder.Append((object) this.<Test>__Field); stringBuilder.Append(", Integer = "); stringBuilder.Append((object) this.<Integer>__Field); stringBuilder.Append(", s = "); stringBuilder.Append((object) this.<s>__Field); stringBuilder.Append(" }"); return ((object) stringBuilder).ToString(); }

Sería ineficiente el rendimiento usar la reflexión aquí, cuando tenga todos los metadatos requeridos en el momento de la compilación.

Descompilado usando dotPeek , esta versión puede variar dependiendo del descompilador usado.

Nota: como también se ha descompilado con dotPeek, intente mirar el espacio de nombres de la raíz . Allí encontrarás algo parecido a:

[DebuggerDisplay("//{ Test = {Test}, Integer = {Integer}, s = {s} }", Type = "<Anonymous Type>")] internal sealed class <>__AnonymousType0<<Test>

Este es un ejemplo de lo que genera el compilado, cuando define objetos anónimos.