Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ToString on an anonymous type work?

Tags:

I was messing with anonymous types, and I accidentally outputted it onto the console. It looked basically how I defined it.

Here's a short program that reproduces it:

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);     } } 

Now, the output is:

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

I tried using dotPeek to get into the assembly to find out why, but it was no help.[1] Here's the dotPeek'd code:

// 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);   } } 

So not much different, at all.

So how does it work? How does it output it like that?

Notes:

[1]: I forgot to turn on "Show compiler-generated code", that's the reason I didn't get how it works.

like image 747
It'sNotALie. Avatar asked May 28 '13 14:05

It'sNotALie.


People also ask

How does ToString work C#?

ToString() method, it returns the fully qualified name of the class. But for some class's/struct's (like Int32 ) it returns a string correspoding to the object (value of the integer).

What keyword do you use to declare an anonymous type?

Essentially an anonymous type is a reference type and can be defined using the var keyword. You can have one or more properties in an anonymous type but all of them are read-only.

What is the difference between an anonymous type and a regular data type?

From the perspective of the common language runtime, an anonymous type is no different from any other reference type, except that it cannot be cast to any type except for object.

Which of the following selects an anonymous type?

Mostly, anonymous types are created using the Select clause of a LINQ queries to return a subset of the properties from each object in the collection.


2 Answers

With anonymous objects...

The compiler generates an internal sealed class that models the anonymous type. The anonymous type is immutable; all the properties are read only. That class contains overrides of Equals() and GetHashCode() that implement value semantics. In addition, the compiler generates an override of ToString() that displays the value of each of the public properties.

Source : link

Please, check @Ilya Ivanov answer to see some code about this subject.

like image 155
HuorSwords Avatar answered Oct 11 '22 12:10

HuorSwords


Just to add some code to HuorSwords answer, compiler will generate ToString method for your example, as given below:

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(); } 

It would be performance inefficient to use reflection here, when you have all required metadata at compile time.

Decompiled using dotPeek, this version may vary depending on used decompiler.

Note: as you also decompiled with dotPeek, try to look at Root Namespace. There you will find something similar to:

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

This is an example of what the compiled generates, when you define anonymous objects.

like image 41
Ilya Ivanov Avatar answered Oct 11 '22 14:10

Ilya Ivanov