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.