The third object is an anonymous type. It is essentially a type that has no name, that the compiler creates for you to allow you to pass or manipulate information without requiring the developer to create a specific type for it.
You see this practice quite a bit in code that uses LINQ, where anonymous types are used to simplify the process of creating projections.
Anonymous types are created using a syntax like:
var anonType = new { Age = 25, Color = "Red", ... };
You can only assign anonymous types to variables of type var
(or object
). Any anonymous types that have the same field names of the same type are considered identical by the compiler.
Anonymous types also define some reasonable equality and hashing semantics for you, so they can be compared and used as dictionary keys.
Anonymous types can be superior to object[] or Tuple. First, they are strongly typed - which means you can't accidentally mix incompatible anonymous types. Second, they allow tools like VisualStudio to provide intellisense. Third, they automatically generate comparison and hashing semantics for you, as mentioned above. Finally, unlike Tuple<>, you can define an anonymous type with any number of fields - which is impractical with Tuple.